The weather here remains hellish so there’s little I can do besides suffering from it.
And yet I’ve spent two hours this morning to implement the main part of NihAV — set implementation. The other crucial part is options handling but I’ll postpone it for later since I can write proof of concept code without it.
Here’s a list of NihAV design guidelines I plan to follow:
- Naming: component functions should be called
na_component_create()
,na_component_destroy()
,na_component_do_something()
. - More generally, prefixing: public functions are prefixed with
na_
, public headers start withna
as well e.g.libnadata/naset.h
. The rest is private to the library. Even other NihAV libraries should use only public interfaces, otherwise you getff_something
andavpriv_that
called from outside and in result you have MPlayer. - NihAV-specific error codes to be used everywhere. Having
AVERROR(EWHATEVER)
andAVERROR_WHATEVER
together is ridiculous. Especially when you have to deal with some error codes being missing from some platform and other being nonportable (what if on nihOS they decided to map ENOMEM to 42? Can you trust error code returned by service run on some remote platform then?).
And here’s how actual set interface looks like:
[sourcecode language=”c”]
#ifndef NA_DATA_SET_H
#define NA_DATA_SET_H
#include “nacommon.h”
struct NASet *na_set_create(NALibrary *lib);
void na_set_destroy(struct NASet *set);
int na_set_add(struct NASet *set, const char *key, void *data);
void* na_set_get(struct NASet *set, const char *key);
void na_set_del(struct NASet *set, const char *key);
struct NASetIterator;
typedef struct NASetEntry {
const char *key;
void *data;
} NASetEntry;
struct NASetIterator* na_set_iterator_get(struct NASet *set);
void na_set_iterator_destroy(struct NASetIterator* it);
int na_set_iterator_next(struct NASetIterator* it, NASetEntry *entry);
void na_set_iterator_reset(struct NASetIterator* it);
#endif
[/sourcecode]
As you can see, it’s nothing special, just basic set (well, it’s really dictionary but NIH terminology applies to this project) manipulation functions plus an iterator to scan through it — quite useful for e.g. showing all options or invoking all registered parsers. Implementation wise it’s simple hash table with djb2 hash.
How you’d forward errors from libc calls? Explicit mapping?
Yes, something like this. Remember, they mostly make sense for I/O and not for other stuff.
I can live with that.