diff options
Diffstat (limited to 'src/encoder_plugin.h')
-rw-r--r-- | src/encoder_plugin.h | 98 |
1 files changed, 96 insertions, 2 deletions
diff --git a/src/encoder_plugin.h b/src/encoder_plugin.h index 95b3da016..33a379115 100644 --- a/src/encoder_plugin.h +++ b/src/encoder_plugin.h @@ -22,6 +22,7 @@ #include <glib.h> +#include <assert.h> #include <stdbool.h> #include <stddef.h> @@ -32,6 +33,10 @@ struct tag; struct encoder { const struct encoder_plugin *plugin; + +#ifndef NDEBUG + bool open, pre_tag, tag, end; +#endif }; struct encoder_plugin { @@ -48,6 +53,8 @@ struct encoder_plugin { void (*close)(struct encoder *encoder); + bool (*end)(struct encoder *encoder, GError **error); + bool (*flush)(struct encoder *encoder, GError **error); bool (*pre_tag)(struct encoder *encoder, GError **error); @@ -73,6 +80,10 @@ encoder_struct_init(struct encoder *encoder, const struct encoder_plugin *plugin) { encoder->plugin = plugin; + +#ifndef NDEBUG + encoder->open = false; +#endif } /** @@ -98,6 +109,8 @@ encoder_init(const struct encoder_plugin *plugin, static inline void encoder_finish(struct encoder *encoder) { + assert(!encoder->open); + encoder->plugin->finish(encoder); } @@ -116,7 +129,14 @@ static inline bool encoder_open(struct encoder *encoder, struct audio_format *audio_format, GError **error) { - return encoder->plugin->open(encoder, audio_format, error); + assert(!encoder->open); + + bool success = encoder->plugin->open(encoder, audio_format, error); +#ifndef NDEBUG + encoder->open = success; + encoder->pre_tag = encoder->tag = encoder->end = false; +#endif + return success; } /** @@ -128,8 +148,43 @@ encoder_open(struct encoder *encoder, struct audio_format *audio_format, static inline void encoder_close(struct encoder *encoder) { + assert(encoder->open); + if (encoder->plugin->close != NULL) encoder->plugin->close(encoder); + +#ifndef NDEBUG + encoder->open = false; +#endif +} + +/** + * Ends the stream: flushes the encoder object, generate an + * end-of-stream marker (if applicable), make everything which might + * currently be buffered available by encoder_read(). + * + * After this function has been called, the encoder may not be usable + * for more data, and only encoder_read() and encoder_close() can be + * called. + * + * @param encoder the encoder + * @param error location to store the error occuring, or NULL to ignore errors. + * @return true on success + */ +static inline bool +encoder_end(struct encoder *encoder, GError **error) +{ + assert(encoder->open); + assert(!encoder->end); + +#ifndef NDEBUG + encoder->end = true; +#endif + + /* this method is optional */ + return encoder->plugin->end != NULL + ? encoder->plugin->end(encoder, error) + : true; } /** @@ -143,6 +198,11 @@ encoder_close(struct encoder *encoder) static inline bool encoder_flush(struct encoder *encoder, GError **error) { + assert(encoder->open); + assert(!encoder->pre_tag); + assert(!encoder->tag); + assert(!encoder->end); + /* this method is optional */ return encoder->plugin->flush != NULL ? encoder->plugin->flush(encoder, error) @@ -162,10 +222,20 @@ encoder_flush(struct encoder *encoder, GError **error) static inline bool encoder_pre_tag(struct encoder *encoder, GError **error) { + assert(encoder->open); + assert(!encoder->pre_tag); + assert(!encoder->tag); + assert(!encoder->end); + /* this method is optional */ - return encoder->plugin->pre_tag != NULL + bool success = encoder->plugin->pre_tag != NULL ? encoder->plugin->pre_tag(encoder, error) : true; + +#ifndef NDEBUG + encoder->pre_tag = success; +#endif + return success; } /** @@ -182,6 +252,15 @@ encoder_pre_tag(struct encoder *encoder, GError **error) static inline bool encoder_tag(struct encoder *encoder, const struct tag *tag, GError **error) { + assert(encoder->open); + assert(!encoder->pre_tag); + assert(encoder->tag); + assert(!encoder->end); + +#ifndef NDEBUG + encoder->tag = false; +#endif + /* this method is optional */ return encoder->plugin->tag != NULL ? encoder->plugin->tag(encoder, tag, error) @@ -201,6 +280,11 @@ static inline bool encoder_write(struct encoder *encoder, const void *data, size_t length, GError **error) { + assert(encoder->open); + assert(!encoder->pre_tag); + assert(!encoder->tag); + assert(!encoder->end); + return encoder->plugin->write(encoder, data, length, error); } @@ -215,6 +299,16 @@ encoder_write(struct encoder *encoder, const void *data, size_t length, static inline size_t encoder_read(struct encoder *encoder, void *dest, size_t length) { + assert(encoder->open); + assert(!encoder->pre_tag || !encoder->tag); + +#ifndef NDEBUG + if (encoder->pre_tag) { + encoder->pre_tag = false; + encoder->tag = true; + } +#endif + return encoder->plugin->read(encoder, dest, length); } |