aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--src/encoder/vorbis_encoder.c11
-rw-r--r--src/encoder_plugin.h24
-rw-r--r--src/output/httpd_output_plugin.c2
-rw-r--r--src/output/shout_plugin.c2
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);
@@ -148,8 +150,30 @@ encoder_flush(struct encoder *encoder, GError **error)
}
/**
+ * 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);