Commit 838f7cd2 authored by Max Kellermann's avatar Max Kellermann

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.
parent 13539961
...@@ -6,6 +6,8 @@ ver 0.16.4 (2011/??/??) ...@@ -6,6 +6,8 @@ ver 0.16.4 (2011/??/??)
- ffmpeg: workaround for semantic API change in recent ffmpeg versions - ffmpeg: workaround for semantic API change in recent ffmpeg versions
- flac: validate the sample rate when scanning the tag - flac: validate the sample rate when scanning the tag
- wavpack: obey all decoder commands, stop at CUE track border - wavpack: obey all decoder commands, stop at CUE track border
* encoder:
- vorbis: don't send end-of-stream on flush
* output: * output:
- alsa: fix SIGFPE when alsa announces a period size of 0 - alsa: fix SIGFPE when alsa announces a period size of 0
......
...@@ -266,6 +266,15 @@ vorbis_encoder_flush(struct encoder *_encoder, G_GNUC_UNUSED GError **error) ...@@ -266,6 +266,15 @@ vorbis_encoder_flush(struct encoder *_encoder, G_GNUC_UNUSED GError **error)
{ {
struct vorbis_encoder *encoder = (struct vorbis_encoder *)_encoder; 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_analysis_wrote(&encoder->vd, 0);
vorbis_encoder_blockout(encoder); vorbis_encoder_blockout(encoder);
...@@ -366,6 +375,7 @@ vorbis_encoder_read(struct encoder *_encoder, void *_dest, size_t length) ...@@ -366,6 +375,7 @@ vorbis_encoder_read(struct encoder *_encoder, void *_dest, size_t length)
if (ret == 0 && encoder->flush) { if (ret == 0 && encoder->flush) {
encoder->flush = false; encoder->flush = false;
ret = ogg_stream_flush(&encoder->os, &page); ret = ogg_stream_flush(&encoder->os, &page);
} }
if (ret == 0) if (ret == 0)
...@@ -398,6 +408,7 @@ const struct encoder_plugin vorbis_encoder_plugin = { ...@@ -398,6 +408,7 @@ const struct encoder_plugin vorbis_encoder_plugin = {
.open = vorbis_encoder_open, .open = vorbis_encoder_open,
.close = vorbis_encoder_close, .close = vorbis_encoder_close,
.flush = vorbis_encoder_flush, .flush = vorbis_encoder_flush,
.pre_tag = vorbis_encoder_pre_tag,
.tag = vorbis_encoder_tag, .tag = vorbis_encoder_tag,
.write = vorbis_encoder_write, .write = vorbis_encoder_write,
.read = vorbis_encoder_read, .read = vorbis_encoder_read,
......
...@@ -50,6 +50,8 @@ struct encoder_plugin { ...@@ -50,6 +50,8 @@ struct encoder_plugin {
bool (*flush)(struct encoder *encoder, GError **error); bool (*flush)(struct encoder *encoder, GError **error);
bool (*pre_tag)(struct encoder *encoder, GError **error);
bool (*tag)(struct encoder *encoder, const struct tag *tag, bool (*tag)(struct encoder *encoder, const struct tag *tag,
GError **error); GError **error);
...@@ -148,8 +150,30 @@ encoder_flush(struct encoder *encoder, 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. * 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 encoder the encoder
* @param tag the tag object * @param tag the tag object
* @param error location to store the error occuring, or NULL to ignore errors. * @param error location to store the error occuring, or NULL to ignore errors.
......
...@@ -523,7 +523,7 @@ httpd_output_tag(void *data, const struct tag *tag) ...@@ -523,7 +523,7 @@ httpd_output_tag(void *data, const struct tag *tag)
/* flush the current stream, and end it */ /* flush the current stream, and end it */
encoder_flush(httpd->encoder, NULL); encoder_pre_tag(httpd->encoder, NULL);
httpd_output_encoder_to_clients(httpd); httpd_output_encoder_to_clients(httpd);
/* send the tag to the encoder - which starts a new /* send the tag to the encoder - which starts a new
......
...@@ -511,7 +511,7 @@ static void my_shout_set_tag(void *data, ...@@ -511,7 +511,7 @@ static void my_shout_set_tag(void *data,
if (sd->encoder->plugin->tag != NULL) { if (sd->encoder->plugin->tag != NULL) {
/* encoder plugin supports stream tags */ /* encoder plugin supports stream tags */
ret = encoder_flush(sd->encoder, &error); ret = encoder_pre_tag(sd->encoder, &error);
if (!ret) { if (!ret) {
g_warning("%s", error->message); g_warning("%s", error->message);
g_error_free(error); g_error_free(error);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment