From 838f7cd210dbd3f071d48d54c168c123c3d20c58 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 20 Jul 2011 20:54:34 +0200 Subject: [PATCH] encoder_plugin: add method pre_tag() In the "vorbis" plugin, this is a copy of the old flush() method, while flush() gets a lot of code remove, it just sets the "flush" flag and nothing else. It doesn't start a new stream now, which should fix a few problems in some players. --- NEWS | 2 ++ src/encoder/vorbis_encoder.c | 11 +++++++++++ src/encoder_plugin.h | 24 ++++++++++++++++++++++++ src/output/httpd_output_plugin.c | 2 +- src/output/shout_plugin.c | 2 +- 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index b642c820b..3cc704ef0 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ ver 0.16.4 (2011/??/??) - ffmpeg: workaround for semantic API change in recent ffmpeg versions - flac: validate the sample rate when scanning the tag - wavpack: obey all decoder commands, stop at CUE track border +* encoder: + - vorbis: don't send end-of-stream on flush * output: - alsa: fix SIGFPE when alsa announces a period size of 0 diff --git a/src/encoder/vorbis_encoder.c b/src/encoder/vorbis_encoder.c index 08147be1c..38a998bd2 100644 --- a/src/encoder/vorbis_encoder.c +++ b/src/encoder/vorbis_encoder.c @@ -266,6 +266,15 @@ vorbis_encoder_flush(struct encoder *_encoder, G_GNUC_UNUSED GError **error) { struct vorbis_encoder *encoder = (struct vorbis_encoder *)_encoder; + encoder->flush = true; + return true; +} + +static bool +vorbis_encoder_pre_tag(struct encoder *_encoder, G_GNUC_UNUSED GError **error) +{ + struct vorbis_encoder *encoder = (struct vorbis_encoder *)_encoder; + vorbis_analysis_wrote(&encoder->vd, 0); vorbis_encoder_blockout(encoder); @@ -366,6 +375,7 @@ vorbis_encoder_read(struct encoder *_encoder, void *_dest, size_t length) if (ret == 0 && encoder->flush) { encoder->flush = false; ret = ogg_stream_flush(&encoder->os, &page); + } if (ret == 0) @@ -398,6 +408,7 @@ const struct encoder_plugin vorbis_encoder_plugin = { .open = vorbis_encoder_open, .close = vorbis_encoder_close, .flush = vorbis_encoder_flush, + .pre_tag = vorbis_encoder_pre_tag, .tag = vorbis_encoder_tag, .write = vorbis_encoder_write, .read = vorbis_encoder_read, diff --git a/src/encoder_plugin.h b/src/encoder_plugin.h index 13fb231f4..fb00413e6 100644 --- a/src/encoder_plugin.h +++ b/src/encoder_plugin.h @@ -50,6 +50,8 @@ struct encoder_plugin { bool (*flush)(struct encoder *encoder, GError **error); + bool (*pre_tag)(struct encoder *encoder, GError **error); + bool (*tag)(struct encoder *encoder, const struct tag *tag, GError **error); @@ -147,9 +149,31 @@ encoder_flush(struct encoder *encoder, GError **error) : true; } +/** + * Prepare for sending a tag to the encoder. This is used by some + * encoders to flush the previous sub-stream, in preparation to begin + * a new one. + * + * @param encoder the encoder + * @param tag the tag object + * @param error location to store the error occuring, or NULL to ignore errors. + * @return true on success + */ +static inline bool +encoder_pre_tag(struct encoder *encoder, GError **error) +{ + /* this method is optional */ + return encoder->plugin->pre_tag != NULL + ? encoder->plugin->pre_tag(encoder, error) + : true; +} + /** * Sends a tag to the encoder. * + * Instructions: call encoder_pre_tag(); then obtain flushed data with + * encoder_read(); finally call encoder_tag(). + * * @param encoder the encoder * @param tag the tag object * @param error location to store the error occuring, or NULL to ignore errors. diff --git a/src/output/httpd_output_plugin.c b/src/output/httpd_output_plugin.c index 0137965a6..40ad05c3d 100644 --- a/src/output/httpd_output_plugin.c +++ b/src/output/httpd_output_plugin.c @@ -523,7 +523,7 @@ httpd_output_tag(void *data, const struct tag *tag) /* flush the current stream, and end it */ - encoder_flush(httpd->encoder, NULL); + encoder_pre_tag(httpd->encoder, NULL); httpd_output_encoder_to_clients(httpd); /* send the tag to the encoder - which starts a new diff --git a/src/output/shout_plugin.c b/src/output/shout_plugin.c index 5e1ef762a..35efd9fc7 100644 --- a/src/output/shout_plugin.c +++ b/src/output/shout_plugin.c @@ -511,7 +511,7 @@ static void my_shout_set_tag(void *data, if (sd->encoder->plugin->tag != NULL) { /* encoder plugin supports stream tags */ - ret = encoder_flush(sd->encoder, &error); + ret = encoder_pre_tag(sd->encoder, &error); if (!ret) { g_warning("%s", error->message); g_error_free(error);