encoder/vorbis: generate end-of-stream packet when playback ends
Add the encoder_plugin method end(). This is important for the recorder plugin.
This commit is contained in:
parent
466c337bcb
commit
5acee73fc8
1
NEWS
1
NEWS
|
@ -5,6 +5,7 @@ ver 0.16.8 (2012/??/??)
|
||||||
- ffmpeg: read the "year" tag
|
- ffmpeg: read the "year" tag
|
||||||
* encoder:
|
* encoder:
|
||||||
- vorbis: generate end-of-stream packet before tag
|
- vorbis: generate end-of-stream packet before tag
|
||||||
|
- vorbis: generate end-of-stream packet when playback ends
|
||||||
* output:
|
* output:
|
||||||
- jack: check for connection failure before starting playback
|
- jack: check for connection failure before starting playback
|
||||||
- jack: workaround for libjack1 crash bug
|
- jack: workaround for libjack1 crash bug
|
||||||
|
|
|
@ -354,6 +354,7 @@ const struct encoder_plugin flac_encoder_plugin = {
|
||||||
.finish = flac_encoder_finish,
|
.finish = flac_encoder_finish,
|
||||||
.open = flac_encoder_open,
|
.open = flac_encoder_open,
|
||||||
.close = flac_encoder_close,
|
.close = flac_encoder_close,
|
||||||
|
.end = flac_encoder_flush,
|
||||||
.flush = flac_encoder_flush,
|
.flush = flac_encoder_flush,
|
||||||
.write = flac_encoder_write,
|
.write = flac_encoder_write,
|
||||||
.read = flac_encoder_read,
|
.read = flac_encoder_read,
|
||||||
|
|
|
@ -300,6 +300,7 @@ const struct encoder_plugin twolame_encoder_plugin = {
|
||||||
.finish = twolame_encoder_finish,
|
.finish = twolame_encoder_finish,
|
||||||
.open = twolame_encoder_open,
|
.open = twolame_encoder_open,
|
||||||
.close = twolame_encoder_close,
|
.close = twolame_encoder_close,
|
||||||
|
.end = twolame_encoder_flush,
|
||||||
.flush = twolame_encoder_flush,
|
.flush = twolame_encoder_flush,
|
||||||
.write = twolame_encoder_write,
|
.write = twolame_encoder_write,
|
||||||
.read = twolame_encoder_read,
|
.read = twolame_encoder_read,
|
||||||
|
|
|
@ -405,6 +405,7 @@ const struct encoder_plugin vorbis_encoder_plugin = {
|
||||||
.finish = vorbis_encoder_finish,
|
.finish = vorbis_encoder_finish,
|
||||||
.open = vorbis_encoder_open,
|
.open = vorbis_encoder_open,
|
||||||
.close = vorbis_encoder_close,
|
.close = vorbis_encoder_close,
|
||||||
|
.end = vorbis_encoder_pre_tag,
|
||||||
.flush = vorbis_encoder_flush,
|
.flush = vorbis_encoder_flush,
|
||||||
.pre_tag = vorbis_encoder_pre_tag,
|
.pre_tag = vorbis_encoder_pre_tag,
|
||||||
.tag = vorbis_encoder_tag,
|
.tag = vorbis_encoder_tag,
|
||||||
|
|
|
@ -35,7 +35,7 @@ struct encoder {
|
||||||
const struct encoder_plugin *plugin;
|
const struct encoder_plugin *plugin;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
bool open, pre_tag, tag;
|
bool open, pre_tag, tag, end;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,6 +53,8 @@ struct encoder_plugin {
|
||||||
|
|
||||||
void (*close)(struct encoder *encoder);
|
void (*close)(struct encoder *encoder);
|
||||||
|
|
||||||
|
bool (*end)(struct encoder *encoder, GError **error);
|
||||||
|
|
||||||
bool (*flush)(struct encoder *encoder, GError **error);
|
bool (*flush)(struct encoder *encoder, GError **error);
|
||||||
|
|
||||||
bool (*pre_tag)(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);
|
bool success = encoder->plugin->open(encoder, audio_format, error);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
encoder->open = success;
|
encoder->open = success;
|
||||||
encoder->pre_tag = encoder->tag = false;
|
encoder->pre_tag = encoder->tag = encoder->end = false;
|
||||||
#endif
|
#endif
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -156,6 +158,35 @@ encoder_close(struct encoder *encoder)
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flushes an encoder object, make everything which might currently be
|
* Flushes an encoder object, make everything which might currently be
|
||||||
* buffered available by encoder_read().
|
* buffered available by encoder_read().
|
||||||
|
@ -170,6 +201,7 @@ encoder_flush(struct encoder *encoder, GError **error)
|
||||||
assert(encoder->open);
|
assert(encoder->open);
|
||||||
assert(!encoder->pre_tag);
|
assert(!encoder->pre_tag);
|
||||||
assert(!encoder->tag);
|
assert(!encoder->tag);
|
||||||
|
assert(!encoder->end);
|
||||||
|
|
||||||
/* this method is optional */
|
/* this method is optional */
|
||||||
return encoder->plugin->flush != NULL
|
return encoder->plugin->flush != NULL
|
||||||
|
@ -193,6 +225,7 @@ encoder_pre_tag(struct encoder *encoder, GError **error)
|
||||||
assert(encoder->open);
|
assert(encoder->open);
|
||||||
assert(!encoder->pre_tag);
|
assert(!encoder->pre_tag);
|
||||||
assert(!encoder->tag);
|
assert(!encoder->tag);
|
||||||
|
assert(!encoder->end);
|
||||||
|
|
||||||
/* this method is optional */
|
/* this method is optional */
|
||||||
bool success = encoder->plugin->pre_tag != NULL
|
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->open);
|
||||||
assert(!encoder->pre_tag);
|
assert(!encoder->pre_tag);
|
||||||
assert(encoder->tag);
|
assert(encoder->tag);
|
||||||
|
assert(!encoder->end);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
encoder->tag = false;
|
encoder->tag = false;
|
||||||
|
@ -249,6 +283,7 @@ encoder_write(struct encoder *encoder, const void *data, size_t length,
|
||||||
assert(encoder->open);
|
assert(encoder->open);
|
||||||
assert(!encoder->pre_tag);
|
assert(!encoder->pre_tag);
|
||||||
assert(!encoder->tag);
|
assert(!encoder->tag);
|
||||||
|
assert(!encoder->end);
|
||||||
|
|
||||||
return encoder->plugin->write(encoder, data, length, error);
|
return encoder->plugin->write(encoder, data, length, error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,7 @@ recorder_output_close(void *data)
|
||||||
|
|
||||||
/* flush the encoder and write the rest to the file */
|
/* 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);
|
recorder_output_encoder_to_file(recorder, NULL);
|
||||||
|
|
||||||
/* now really close everything */
|
/* now really close everything */
|
||||||
|
|
|
@ -358,7 +358,7 @@ static void close_shout_conn(struct shout_data * sd)
|
||||||
sd->buf.len = 0;
|
sd->buf.len = 0;
|
||||||
|
|
||||||
if (sd->encoder != NULL) {
|
if (sd->encoder != NULL) {
|
||||||
if (encoder_flush(sd->encoder, NULL))
|
if (encoder_end(sd->encoder, NULL))
|
||||||
write_page(sd, NULL);
|
write_page(sd, NULL);
|
||||||
|
|
||||||
encoder_close(sd->encoder);
|
encoder_close(sd->encoder);
|
||||||
|
|
|
@ -121,7 +121,7 @@ int main(int argc, char **argv)
|
||||||
encoder_to_stdout(encoder);
|
encoder_to_stdout(encoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = encoder_flush(encoder, &error);
|
ret = encoder_end(encoder, &error);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
g_printerr("encoder_flush() failed: %s\n",
|
g_printerr("encoder_flush() failed: %s\n",
|
||||||
error->message);
|
error->message);
|
||||||
|
|
|
@ -99,7 +99,7 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
|
||||||
|
|
||||||
/* finish */
|
/* finish */
|
||||||
|
|
||||||
success = encoder_flush(encoder, NULL);
|
success = encoder_end(encoder, NULL);
|
||||||
assert(success);
|
assert(success);
|
||||||
|
|
||||||
encoder_to_stdout(encoder);
|
encoder_to_stdout(encoder);
|
||||||
|
|
Loading…
Reference in New Issue