aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2012-04-05 00:03:38 +0200
committerMax Kellermann <max@duempel.org>2012-04-05 00:21:53 +0200
commit5acee73fc85e44179120a5818247fc0760038cff (patch)
tree143a8f28c8537041f08ecd64a9d3bfba35a412f4
parent466c337bcb71fb6bca0384300586e7213685d53d (diff)
downloadmpd-5acee73fc85e44179120a5818247fc0760038cff.tar.gz
mpd-5acee73fc85e44179120a5818247fc0760038cff.tar.xz
mpd-5acee73fc85e44179120a5818247fc0760038cff.zip
encoder/vorbis: generate end-of-stream packet when playback ends
Add the encoder_plugin method end(). This is important for the recorder plugin.
-rw-r--r--NEWS1
-rw-r--r--src/encoder/flac_encoder.c1
-rw-r--r--src/encoder/twolame_encoder.c1
-rw-r--r--src/encoder/vorbis_encoder.c1
-rw-r--r--src/encoder_plugin.h39
-rw-r--r--src/output/recorder_output_plugin.c2
-rw-r--r--src/output/shout_plugin.c2
-rw-r--r--test/run_encoder.c2
-rw-r--r--test/test_vorbis_encoder.c2
9 files changed, 45 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index caa3cd073..5a215dadd 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ ver 0.16.8 (2012/??/??)
- ffmpeg: read the "year" tag
* encoder:
- vorbis: generate end-of-stream packet before tag
+ - vorbis: generate end-of-stream packet when playback ends
* output:
- jack: check for connection failure before starting playback
- jack: workaround for libjack1 crash bug
diff --git a/src/encoder/flac_encoder.c b/src/encoder/flac_encoder.c
index 6389513ef..e2c455e3a 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 d20af551b..073c3128f 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 519d7cbf6..9f09b2ac7 100644
--- a/src/encoder/vorbis_encoder.c
+++ b/src/encoder/vorbis_encoder.c
@@ -405,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 af3f76a40..70eee51a2 100644
--- a/src/encoder_plugin.h
+++ b/src/encoder_plugin.h
@@ -35,7 +35,7 @@ struct encoder {
const struct encoder_plugin *plugin;
#ifndef NDEBUG
- bool open, pre_tag, tag;
+ bool open, pre_tag, tag, end;
#endif
};
@@ -53,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);
@@ -132,7 +134,7 @@ encoder_open(struct encoder *encoder, struct audio_format *audio_format,
bool success = encoder->plugin->open(encoder, audio_format, error);
#ifndef NDEBUG
encoder->open = success;
- encoder->pre_tag = encoder->tag = false;
+ encoder->pre_tag = encoder->tag = encoder->end = false;
#endif
return success;
}
@@ -157,6 +159,35 @@ encoder_close(struct encoder *encoder)
}
/**
+ * 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;
+}
+
+/**
* Flushes an encoder object, make everything which might currently be
* buffered available by encoder_read().
*
@@ -170,6 +201,7 @@ 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
@@ -193,6 +225,7 @@ 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 */
bool success = encoder->plugin->pre_tag != NULL
@@ -222,6 +255,7 @@ 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;
@@ -249,6 +283,7 @@ encoder_write(struct encoder *encoder, const void *data, size_t length,
assert(encoder->open);
assert(!encoder->pre_tag);
assert(!encoder->tag);
+ assert(!encoder->end);
return encoder->plugin->write(encoder, data, length, error);
}
diff --git a/src/output/recorder_output_plugin.c b/src/output/recorder_output_plugin.c
index 10d64106c..2f088a107 100644
--- a/src/output/recorder_output_plugin.c
+++ b/src/output/recorder_output_plugin.c
@@ -191,7 +191,7 @@ recorder_output_close(void *data)
/* flush the encoder and write the rest to the file */
- if (encoder_flush(recorder->encoder, NULL))
+ if (encoder_end(recorder->encoder, NULL))
recorder_output_encoder_to_file(recorder, NULL);
/* now really close everything */
diff --git a/src/output/shout_plugin.c b/src/output/shout_plugin.c
index 35efd9fc7..27ef3b993 100644
--- a/src/output/shout_plugin.c
+++ b/src/output/shout_plugin.c
@@ -358,7 +358,7 @@ static void close_shout_conn(struct shout_data * sd)
sd->buf.len = 0;
if (sd->encoder != NULL) {
- if (encoder_flush(sd->encoder, NULL))
+ if (encoder_end(sd->encoder, NULL))
write_page(sd, NULL);
encoder_close(sd->encoder);
diff --git a/test/run_encoder.c b/test/run_encoder.c
index 16e633029..4c05a06c7 100644
--- a/test/run_encoder.c
+++ b/test/run_encoder.c
@@ -121,7 +121,7 @@ int main(int argc, char **argv)
encoder_to_stdout(encoder);
}
- ret = encoder_flush(encoder, &error);
+ ret = encoder_end(encoder, &error);
if (!ret) {
g_printerr("encoder_flush() failed: %s\n",
error->message);
diff --git a/test/test_vorbis_encoder.c b/test/test_vorbis_encoder.c
index 370a8a59e..969ab7687 100644
--- a/test/test_vorbis_encoder.c
+++ b/test/test_vorbis_encoder.c
@@ -99,7 +99,7 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
/* finish */
- success = encoder_flush(encoder, NULL);
+ success = encoder_end(encoder, NULL);
assert(success);
encoder_to_stdout(encoder);