diff options
Diffstat (limited to '')
-rw-r--r-- | src/encoder/flac_encoder.c | 1 | ||||
-rw-r--r-- | src/encoder/twolame_encoder.c | 1 | ||||
-rw-r--r-- | src/encoder/vorbis_encoder.c | 3 | ||||
-rw-r--r-- | src/encoder_plugin.h | 98 |
4 files changed, 99 insertions, 4 deletions
diff --git a/src/encoder/flac_encoder.c b/src/encoder/flac_encoder.c index 9f60bdae5..e32588e29 100644 --- a/src/encoder/flac_encoder.c +++ b/src/encoder/flac_encoder.c @@ -354,6 +354,7 @@ const struct encoder_plugin flac_encoder_plugin = { .finish = flac_encoder_finish, .open = flac_encoder_open, .close = flac_encoder_close, + .end = flac_encoder_flush, .flush = flac_encoder_flush, .write = flac_encoder_write, .read = flac_encoder_read, diff --git a/src/encoder/twolame_encoder.c b/src/encoder/twolame_encoder.c index 00ebcc0d7..934b2ab24 100644 --- a/src/encoder/twolame_encoder.c +++ b/src/encoder/twolame_encoder.c @@ -300,6 +300,7 @@ const struct encoder_plugin twolame_encoder_plugin = { .finish = twolame_encoder_finish, .open = twolame_encoder_open, .close = twolame_encoder_close, + .end = twolame_encoder_flush, .flush = twolame_encoder_flush, .write = twolame_encoder_write, .read = twolame_encoder_read, diff --git a/src/encoder/vorbis_encoder.c b/src/encoder/vorbis_encoder.c index 3e9d486b6..fcf2b5135 100644 --- a/src/encoder/vorbis_encoder.c +++ b/src/encoder/vorbis_encoder.c @@ -285,8 +285,6 @@ vorbis_encoder_pre_tag(struct encoder *_encoder, G_GNUC_UNUSED GError **error) vorbis_analysis_init(&encoder->vd, &encoder->vi); vorbis_block_init(&encoder->vd, &encoder->vb); - ogg_stream_reset(&encoder->os); - encoder->flush = true; return true; } @@ -407,6 +405,7 @@ const struct encoder_plugin vorbis_encoder_plugin = { .finish = vorbis_encoder_finish, .open = vorbis_encoder_open, .close = vorbis_encoder_close, + .end = vorbis_encoder_pre_tag, .flush = vorbis_encoder_flush, .pre_tag = vorbis_encoder_pre_tag, .tag = vorbis_encoder_tag, 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); } |