spa-pod.dox 15.2 KB
Newer Older
1
/** \page page_spa_pod SPA POD
2

3
\ref spa_pod (plain old data) is a sort of data container. It is comparable to
Wim Taymans's avatar
Wim Taymans committed
4
DBus Variant or LV2 Atom.
5

jasker5183's avatar
jasker5183 committed
6
7
A POD can express nested structures of objects (with properties), vectors,
arrays, sequences and various primitives types. All information in the POD
8
is laid out sequentially in memory and can be written directly to
9
storage or exchanged between processes or threads without additional
iss's avatar
iss committed
10
marshalling.
11
12

Each POD is made of a 32 bits size followed by a 32 bits type field,
jasker5183's avatar
jasker5183 committed
13
followed by the POD contents. This makes it possible to skip over unknown
Peter Hutterer's avatar
Peter Hutterer committed
14
POD types. The POD start is always aligned to 8 bytes.
15

jasker5183's avatar
jasker5183 committed
16
POD's can be efficiently constructed and parsed in real-time threads without
17
requiring memory allocations.
18

jasker5183's avatar
jasker5183 committed
19
POD's use the SPA type system for the basic types and containers. See
20
21
22
the SPA types for more info.


jasker5183's avatar
jasker5183 committed
23
# Types
24

jasker5183's avatar
jasker5183 committed
25
POD's can contain a number of basic SPA types:
26

jasker5183's avatar
jasker5183 committed
27
28
29
30
31
32
33
34
35
36
- `SPA_TYPE_None`: No value or a NULL pointer.
- `SPA_TYPE_Bool`: A boolean value.
- `SPA_TYPE_Id`: An enumerated value.
- `SPA_TYPE_Int`, `SPA_TYPE_Long`, `SPA_TYPE_Float`, `SPA_TYPE_Double`:
  various numeral types, 32 and 64 bits.
- `SPA_TYPE_String`: A string.
- `SPA_TYPE_Bytes`: A byte array.
- `SPA_TYPE_Rectangle`: A rectangle with width and height.
- `SPA_TYPE_Fraction`: A fraction with numerator and denominator.
- `SPA_TYPE_Bitmap`: An array of bits.
37

jasker5183's avatar
jasker5183 committed
38
POD's can be grouped together in these container types:
39

jasker5183's avatar
jasker5183 committed
40
41
42
43
- `SPA_TYPE_Array`: An array of equal sized objects.
- `SPA_TYPE_Struct`: A collection of types and objects.
- `SPA_TYPE_Object`: An object with properties.
- `SPA_TYPE_Sequence`: A timed sequence of POD's.
44

jasker5183's avatar
jasker5183 committed
45
POD's can also contain some extra types:
46

jasker5183's avatar
jasker5183 committed
47
48
49
50
51
52
53
- `SPA_TYPE_Pointer`: A typed pointer in memory.
- `SPA_TYPE_Fd`: A file descriptor.
- `SPA_TYPE_Choice`: A choice of values.
- `SPA_TYPE_Pod`: A generic type for the POD itself.


# Constructing A POD
54
55
56
57
58
59
60

A POD is usually constructed with a `struct spa_pod_builder`. The builder
needs to be initialized with a memory region to write into. It is
also possible to dynamically grow the memory as needed.

The most common way to construct a POD is on the stack. This does
not require any memory allocations. The size of the POD can be
Wim Taymans's avatar
Wim Taymans committed
61
estimated pretty easily and if the buffer is not large enough, an
62
63
appropriate error will be generated.

jasker5183's avatar
jasker5183 committed
64
The code fragment below initializes a POD builder to write into
65
66
the stack allocated buffer.

67
\code{.c}
68
69
uint8_t buffer[4096];
struct spa_pod_builder b;
70
spa_pod_builder_init(&b, buffer, sizeof(buffer));
71
\endcode
72
73
74
75
76

Next we need to write some object into the builder. Let's write
a simple struct with an Int and Float in it. Structs are comparable
to JSON arrays.

77
\code{.c}
78
79
struct spa_pod_frame f;
spa_pod_builder_push_struct(&b, &f);
80
\endcode
81
82
83
84
85

First we open the struct container, the `struct spa_pod_frame` keeps
track of the container context. Next we add some values to
the container like this:

86
\code{.c}
87
88
spa_pod_builder_int(&b, 5);
spa_pod_builder_float(&b, 3.1415f);
89
\endcode
90

iss's avatar
iss committed
91
Then we close the container by popping the frame again:
92

93
\code{.c}
94
95
struct spa_pod *pod;
pod = spa_pod_builder_pop(&b, &f);
96
\endcode
97
98
99
100

`spa_pod_builder_pop()` returns a reference to the object we completed
on the stack.

jasker5183's avatar
jasker5183 committed
101
## Using varargs Builder
102
103
104

We can also use the following construct to make POD objects:

105
\code{.c}
106
107
108
109
110
spa_pod_builder_push_struct(&b, &f);
spa_pod_builder_add(&b,
	SPA_POD_Int(5),
	SPA_POD_Float(3.1415f));
pod = spa_pod_builder_pop(&b, &f);
111
\endcode
112
113
114

Or even shorter:

115
\code{.c}
116
117
118
pod = spa_pod_builder_add_struct(&b,
	SPA_POD_Int(5),
	SPA_POD_Float(3.1415f));
119
\endcode
120

jasker5183's avatar
jasker5183 committed
121
122
It's not possible to use the varargs builder to make a sequence or
array, use the normal builder methods for that.
123

jasker5183's avatar
jasker5183 committed
124
## Making Objects
125
126
127
128
129
130

POD objects are containers for properties and are comparable to JSON
objects.

Start by pushing an object:

131
\code{.c}
132
spa_pod_builder_push_object(&b, &f, SPA_TYPE_OBJECT_Props, SPA_PARAM_Props);
133
\endcode
134
135

An object requires an object type (`SPA_TYPE_OBJECT_Props`) and a context
jasker5183's avatar
jasker5183 committed
136
ID (`SPA_PARAM_Props`). The object type defines the properties that can be
137
138
139
140
141
added to the object and their meaning. The SPA type system allows you to
make this connection (See the type system).

Next we can push some properties in the object:

142
\code{.c}
143
144
145
146
spa_pod_builder_prop(&b, SPA_PROP_device, 0);
spa_pod_builder_string(&b, "hw:0");
spa_pod_builder_prop(&b, SPA_PROP_frequency, 0);
spa_pod_builder_float(&b, 440.0);
147
\endcode
148
149
150
151
152
153
154

As can be seen, we always need to push a prop (with key and flags)
and then the associated value. For performance reasons it is a good
idea to always push (and parse) the object keys in ascending order.

Don't forget to pop the result when the object is finished:

155
\code{.c}
156
pod = spa_pod_builder_pop(&b, &f);
157
\endcode
158
159
160

There is a shortcut for making objects:

161
\code{.c}
162
163
164
165
pod = spa_pod_builder_add_object(&b,
	SPA_TYPE_OBJECT_Props, SPA_PARAM_Props,
	SPA_PROP_device,    SPA_POD_String("hw:0"),
	SPA_PROP_frequency, SPA_POD_Float(440.0f));
166
\endcode
167

jasker5183's avatar
jasker5183 committed
168
## Choice Values
169
170
171

It is possible to express ranges or enumerations of possible
values for properties (and to some extend structs). This is achieved
jasker5183's avatar
jasker5183 committed
172
with choice values.
173
174
175
176
177

Choice values are really just a choice type and an array of choice values
(of the same type). Depending on the choice type, the array values are
interpreted in different ways:

jasker5183's avatar
jasker5183 committed
178
179
180
181
182
- `SPA_CHOICE_None`: No choice, first value is current.
- `SPA_CHOICE_Range`: Range: default, min, max.
- `SPA_CHOICE_Step`: Range with step: default, min, max, step.
- `SPA_CHOICE_Enum`: Enum: default, alternative,...
- `SPA_CHOICE_Flags`: Bitmask of flags.
183

jasker5183's avatar
jasker5183 committed
184
Let's illustrate this with a props object that specifies a range of
185
186
possible values for the frequency:

187
\code{.c}
188
189
190
191
192
struct spa_pod_frame f2;

spa_pod_builder_push_object(&b, &f, SPA_TYPE_OBJECT_Props, SPA_PARAM_Props);
spa_pod_builder_prop(&b, SPA_PROP_frequency, 0);
spa_pod_builder_push_choice(&b, &f2, SPA_CHOICE_Range, 0);
193
194
195
spa_pod_builder_float(&b, 440.0);   //  default
spa_pod_builder_float(&b, 110.0);   //  min
spa_pod_builder_float(&b, 880.0);   //  min
196
197
pod = spa_pod_builder_pop(&b, &f2);
pod = spa_pod_builder_pop(&b, &f);
198
\endcode
199

jasker5183's avatar
jasker5183 committed
200
201
As you can see, first push the choice as a range, then the values. A range
choice expects at least three values, the default value, minimum and maximum
202
values. There is a shortcut for this as well using varargs:
203

204
\code{.c}
205
206
207
pod = spa_pod_builder_add_object(&b,
	SPA_TYPE_OBJECT_Props, SPA_PARAM_Props,
	SPA_PROP_frequency, SPA_POD_CHOICE_RANGE_Float(440.0f, 110.0f, 880.0f));
208
\endcode
209

jasker5183's avatar
jasker5183 committed
210
## Choice Examples
211
212
213
214

This is a description of a possible `SPA_TYPE_OBJECT_Format` as used when
enumerating allowed formats (`SPA_PARAM_EnumFormat`) in SPA objects:

215
\code{.c}
216
217
pod = spa_pod_builder_add_object(&b,
	SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
218
	//  specify the media type and subtype
219
220
	SPA_FORMAT_mediaType,      SPA_POD_Id(SPA_MEDIA_TYPE_audio),
	SPA_FORMAT_mediaSubtype,   SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
221
	//  audio/raw properties
222
	SPA_FORMAT_AUDIO_format,   SPA_POD_CHOICE_ENUM_Id(
223
224
225
226
					SPA_AUDIO_FORMAT_S16, //  default
					SPA_AUDIO_FORMAT_S16, //  alternative1
					SPA_AUDIO_FORMAT_S32, //  alternative2
					SPA_AUDIO_FORMAT_f32  //  alternative3
227
228
				   ),
	SPA_FORMAT_AUDIO_rate,     SPA_POD_CHOICE_RANGE_Int(
229
230
231
					44100,		//  default
					8000,		//  min
					192000		//  max
232
233
				   ),
	SPA_FORMAT_AUDIO_channels, SPA_POD_Int(2));
234
\endcode
235
236
237

## Fixate

238
We can remove all choice values from the object with the
239
240
241
242
243
244
245
`spa_pod_object_fixate()` method. This modifies the pod in-place and sets all
choice properties to `SPA_CHOICE_None`, forcing the default value as the
only available value in the choice.

Running fixate on our previous example would result in an object equivalent
to:

246
\code{.c}
247
248
pod = spa_pod_builder_add_object(&b,
	SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
249
	//  specify the media type and subtype
250
251
	SPA_FORMAT_mediaType,      SPA_POD_Id(SPA_MEDIA_TYPE_audio),
	SPA_FORMAT_mediaSubtype,   SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
252
	//  audio/raw properties
253
254
255
	SPA_FORMAT_AUDIO_format,   SPA_POD_Id(SPA_AUDIO_FORMAT_S16),
	SPA_FORMAT_AUDIO_rate,     SPA_POD_Int(44100),
	SPA_FORMAT_AUDIO_channels, SPA_POD_Int(2));
256
\endcode
257
258


jasker5183's avatar
jasker5183 committed
259
# Parsing A POD
260

jasker5183's avatar
jasker5183 committed
261
Parsing a POD usually consists of:
262

jasker5183's avatar
jasker5183 committed
263
264
265
266
267
268
- Validating if raw bytes + size can contain a valid POD.
- Inspecting the type of a POD.
- Looping over the items in an object or struct.
- Getting data out of POD's.

## Validating Bytes
269
270
271
272
273

Use `spa_pod_from_data()` to check if maxsize of bytes in data contain
a POD at the size bytes starting at offset. This function checks that
the POD size will fit and not overflow.

274
\code{.c}
275
276
struct spa_pod *pod;
pod = spa_pod_from_data(data, maxsize, offset, size);
277
\endcode
278

jasker5183's avatar
jasker5183 committed
279
## Checking The Type Of POD
280
281
282
283
284
285
286
287
288

Use one of `spa_pod_is_bool()`, `spa_pod_is_int()`, etc to check
for the type of the pod. For simple (non-container) types,
`spa_pod_get_bool()`, `spa_pod_get_int()` etc can be used to
extract the value of the pod.

`spa_pod_is_object_type()` can be used to check if the POD contains
an object of the expected type.

jasker5183's avatar
jasker5183 committed
289
## Struct Fields
290

jasker5183's avatar
jasker5183 committed
291
To iterate over the fields of a struct use:
292

293
\code{.c}
294
295
296
297
struct spa_pod *pod, *obj;
SPA_POD_STRUCT_FOREACH(obj, pod) {
	printf("field type:%d\n", pod->type);
}
298
\endcode
299

jasker5183's avatar
jasker5183 committed
300
For parsing structs it is usually much easier to use the parser
301
302
303
304
below.

## Object Properties

305
To iterate over the properties in an object you can do:
306

307
\code{.c}
308
309
310
311
312
struct spa_pod_prop *prop;
struct spa_pod_object *obj = (struct spa_pod_object*)pod;
SPA_POD_OBJECT_FOREACH(pod, prop) {
	printf("prop key:%d\n", prop->key);
}
313
\endcode
314
315
316
317
318

There is a function to retrieve the property for a certain key
in the object. If the properties of the object are in ascending
order, you can start searching from the previous key.

319
\code{.c}
320
321
struct spa_pod_prop *prop;
prop = spa_pod_find_prop(obj, NULL, SPA_FORMAT_AUDIO_format);
322
  //  .. use first prop
323
prop = spa_pod_find_prop(obj, prop, SPA_FORMAT_AUDIO_rate);
324
325
  //  .. use next prop
\endcode
326
327
328
329
330

## Parser

Similar to the builder, there is a parser object as well.

Wim Taymans's avatar
Wim Taymans committed
331
332
If the fields in a struct are known, it is much easier to use the
parser. Similarly, if the object type (and thus its keys) are known,
333
334
335
336
the parser is easier.

First initialize a `struct spa_pod_parser`:

337
\code{.c}
338
339
struct spa_pod_parser p;
spa_pod_parser_pod(&p, obj);
340
\endcode
341
342
343
344

You can then enter containers such as objects or structs with a push
operation:

345
\code{.c}
346
347
struct spa_pod_frame f;
spa_pod_parser_push_struct(&p, &f);
348
\endcode
349
350

You need to store the context in a `struct spa_pod_frame` to be able
351
to exit the container again later.
352
353
354
355

You can then parse each field. The parser takes care of moving to the
next field.

356
\code{.c}
357
358
359
360
uint32_t id, val;
spa_pod_parser_get_id(&p, &id);
spa_pod_parser_get_int(&p, &val);
...
361
\endcode
362
363
364

And finally exit the container again:

365
\code{.c}
366
spa_pod_parser_pop(&p, &f);
367
\endcode
368

jasker5183's avatar
jasker5183 committed
369
## Parser With Variable Arguments
370
371
372
373
374
375
376

In most cases, parsing objects is easier with the variable argument
functions. The parse function look like the mirror image of the builder
functions.

To parse a struct:

377
\code{.c}
378
379
380
spa_pod_parser_get_struct(&p,
	SPA_POD_Id(&id),
	SPA_POD_Int(&val));
381
\endcode
382
383
384

To parse properties in an object:

385
\code{.c}
386
387
388
389
390
391
392
393
uint32_t type, subtype, format, rate, channels;
spa_pod_parser_get_object(&p,
	SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
	SPA_FORMAT_mediaType,      SPA_POD_Id(&type),
	SPA_FORMAT_mediaSubtype,   SPA_POD_Id(&subtype),
	SPA_FORMAT_AUDIO_format,   SPA_POD_Id(&format),
	SPA_FORMAT_AUDIO_rate,     SPA_POD_Int(&rate),
	SPA_FORMAT_AUDIO_channels, SPA_POD_Int(&channels));
394
\endcode
395
396
397
398
399
400
401
402

When parsing objects it is possible to have optional fields. You can
make a field optional be parsing it with the `SPA_POD_OPT_` prefix
for the type.

In the next example, the rate and channels fields are optional
and when they are not present, the variables will not be changed.

403
\code{.c}
404
405
406
407
408
409
410
411
uint32_t type, subtype, format, rate = 0, channels = 0;
spa_pod_parser_get_object(&p,
	SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
	SPA_FORMAT_mediaType,      SPA_POD_Id(&type),
	SPA_FORMAT_mediaSubtype,   SPA_POD_Id(&subtype),
	SPA_FORMAT_AUDIO_format,   SPA_POD_Id(&format),
	SPA_FORMAT_AUDIO_rate,     SPA_POD_OPT_Int(&rate),
	SPA_FORMAT_AUDIO_channels, SPA_POD_OPT_Int(&channels));
412
\endcode
413

jasker5183's avatar
jasker5183 committed
414
It is not possible to parse a sequence or array with the parser.
415
416
Use the iterator for this.

jasker5183's avatar
jasker5183 committed
417
## Choice Values
418

jasker5183's avatar
jasker5183 committed
419
420
The parser will handle choice values as long as they are of type
`none`. It will then parse the single value from the choice. When
421
dealing with other choice values, it's possible to parse the
jasker5183's avatar
jasker5183 committed
422
property values into a `struct spa_pod` and then inspect the choice
423
424
425
426
manually, if needed.

Here is an example of parsing the format values as a POD:

427
\code{.c}
428
429
430
431
432
433
434
uint32_t type, subtype;
struct spa_pod *format;
spa_pod_parser_get_object(&p,
	SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
	SPA_FORMAT_mediaType,      SPA_POD_Id(&type),
	SPA_FORMAT_mediaSubtype,   SPA_POD_Id(&subtype),
	SPA_FORMAT_AUDIO_format,   SPA_POD_Pod(&format));
435
\endcode
436
437

`spa_pod_get_values()` is a useful function. It returns a
jasker5183's avatar
jasker5183 committed
438
439
440
`struct spa_pod*` with and array of values. For normal POD's
and choice none values, it simply returns the POD and one value.
For other choice values it returns the choice type and an array
441
442
of values:

443
\code{.c}
444
445
446
447
448
449
450
struct spa_pod *value;
uint32_t n_vals, choice;

value = spa_pod_get_values(pod, &n_vals, &choice);

switch (choice) {
case SPA_CHOICE_None:
451
        //  one single value
452
453
	break;
case SPA_CHOICE_Range:
454
455
        // array of values of type of pod, cast to right type
	// to iterate.
456
457
458
459
460
461
462
463
	uint32_t *v = SPA_POD_BODY(values);
	if (n_vals < 3)
		break;
	printf("default value: %u\n", v[0]);
	printf("min value: %u\n", v[1]);
	printf("max value: %u\n", v[2]);
	break;

464
	//  ...
465
466
467
default:
	break;
}
468
\endcode
469

jasker5183's avatar
jasker5183 committed
470

471
472
# Filter

jasker5183's avatar
jasker5183 committed
473
474
475
Given two POD objects of the same type (object, struct, ..) one can
run a filter and generate a new POD that only contains values that
are compatible with both input POD's.
476

Wim Taymans's avatar
Wim Taymans committed
477
This is, for example, used to find a compatible format between two ports.
478

jasker5183's avatar
jasker5183 committed
479
As an example we can run a filter on two simple POD's:
480

481
\code{.c}
482
483
484
485
486
pod = spa_pod_builder_add_object(&b,
	SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
	SPA_FORMAT_mediaType,      SPA_POD_Id(SPA_MEDIA_TYPE_audio),
	SPA_FORMAT_mediaSubtype,   SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
	SPA_FORMAT_AUDIO_format,   SPA_POD_CHOICE_ENUM_Id(
487
488
489
490
					SPA_AUDIO_FORMAT_S16, //  default
					SPA_AUDIO_FORMAT_S16, //  alternative1
					SPA_AUDIO_FORMAT_S32, //  alternative2
					SPA_AUDIO_FORMAT_f32  //  alternative3
491
492
493
494
495
496
497
				   ));

filter = spa_pod_builder_add_object(&b,
	SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
	SPA_FORMAT_mediaType,      SPA_POD_Id(SPA_MEDIA_TYPE_audio),
	SPA_FORMAT_mediaSubtype,   SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
	SPA_FORMAT_AUDIO_format,   SPA_POD_CHOICE_ENUM_Id(
498
499
500
					SPA_AUDIO_FORMAT_S16, //  default
					SPA_AUDIO_FORMAT_S16, //  alternative1
					SPA_AUDIO_FORMAT_f64  //  alternative2
501
502
503
504
505
				   ));

struct spa_pod *result;
if (spa_pod_filter(&b, &result, pod, filter) < 0)
	goto exit_error;
506
\endcode
507
508
509

Filter will contain a POD equivalent to:

510
\code{.c}
511
512
513
514
515
result = spa_pod_builder_add_object(&b,
	SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
	SPA_FORMAT_mediaType,      SPA_POD_Id(SPA_MEDIA_TYPE_audio),
	SPA_FORMAT_mediaSubtype,   SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
	SPA_FORMAT_AUDIO_format,   SPA_AUDIO_FORMAT_S16);
516
\endcode
517

jasker5183's avatar
jasker5183 committed
518
# POD Layout
519
520
521
522
523
524
525

Each POD has a 32 bits size field, followed by a 32 bits type field. The size
field specifies the size following the type field.

Each POD is aligned to an 8 byte boundary.


526
527
528
529
\addtogroup spa_pod

See: \ref page_spa_pod

530
*/