4 The point of the metadata is to provide some context for each buffer. In
5 the case of audio data, for instance, it would provide the samplerate, bit
6 depth, and channel count.
8 The trick is that there may be multiple types of metadata ganged onto a
9 single buffer. This is why they're going to be a GList. This does mean
10 extra overhead in all cases, but I think it's minimal. The GList type
11 uses a chunk allocater so we're not wasting too much memory or time when
14 The trick is dealing with these structs as they pass through a pipeline,
15 since they have potentially different mutability properties. For
16 instance, if you've got a mp3 decoder connected to a tee, which sends the
17 buffers off to both the decoder and a spectrum analyzer (and then a
18 visualization element). The preferred setup would be where every time a
19 audio/raw metadata comes down the pipe (indicating a potential change in
20 audio format), the audiosink and spectrum would just save off pointers.
22 So when exactly does this metadata go away (deallocated)? Well, that
23 means metadata has to be refcounted. But that gets rather hairy. OK, in
24 the simple case you create a metadata struct, it comes with refcount set
25 to 1. You pass it through, it stays one, eventually someone drops the
26 last reference on the buffer it's tied to, you free the metadata too.
27 Easy. What if you tee? You could go through and for every metadata in
28 the buffer, increment the refcount by the same as the buffer. So in the
29 above case (tee'd), the audiosink and spectrum would get the buffer with a
30 refcount of 2, and it'd have a metadata with refcount 2. Do they ref it
31 each themselves, then unref the buffer? Or do they remove the metadata?
32 Removing the metadata would require a buffer CoW, which would suck, so
33 yes, they'd just ref the metadata.
35 But.... what if they're all in different threads? Then we're off into
36 the magical world of mutexes. Everything with a refcount in a threaded
37 world must be mutexed, else you can do atomic increment and atomic
38 dec&test. Can this be done from C easily? Perhaps it needs to be found
39 from kernel includes via autoconf?
44 The goal in designing the way metadata will be defined and used is to keep
45 it as simple as possible. The basis for accomplishing this is the fact
46 that in order to actually use (rather than just pass) the metadata, you
47 have to know what the fields are, which means you have to have compiled in
48 support for that metadata at build time. Therefore, if you're using
49 metadata, you must have build-time access to the necessary include file
52 So, given that you've got an include file, it would be nice if the whole
53 thing could be contained there. This would limit the need to be linked
54 against something, or have load-time requirements as to that has to be
55 loaded before you are.
57 Given that really all metadata is is a region of memory of a given size
58 with a certain signature, this isn't all that hard. First you lay out the
59 struct that defines the metadata. Then you set up #defines that expand to
60 the size of the struct in question, as well as the four-cc code that
63 The work is done by a few #defines, a la the #defines used in all Gtk
64 objects. The first is a NEW() method that allocates the memory for the
65 metadata and fills in all the normal fields (type, size, utility
66 functions). Because of the way it's defined (as a #define, no less),
67 you'll have to invoke it as META_NEW(meta), since it can't return()
70 Another #define will check to make sure a meta is indeed that type by
71 verifying the type code and size. Theoretically, meta types can overlap
72 with the same fourcc code, as long as they have different sizes. But I
73 probably ought to have a global public registry so people writing things
74 don't conflict. MSFT got that right, at least.
76 So, a hairy problem is what to do when there are utility functions
77 associated with one of these things. One option is to not bother with
78 them. This is very likely a possible solution, since metadata is supposed
79 to be flat memory of a given size. Not much to do to either free or copy