aboutsummaryrefslogtreecommitdiff
path: root/src
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 /src
parent466c337bcb71fb6bca0384300586e7213685d53d (diff)
encoder/vorbis: generate end-of-stream packet when playback ends
Add the encoder_plugin method end(). This is important for the recorder plugin.
Diffstat (limited to 'src')
-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
6 files changed, 42 insertions, 4 deletions
diff --git a/src/encoder/flac_encoder.c b/src/encoder/flac_encoder.c
index 6389513e..e2c455e3 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 d20af551..073c3128 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 519d7cbf..9f09b2ac 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 af3f76a4..70eee51a 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 10d64106..2f088a10 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 35efd9fc..27ef3b99 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);