diff options
author | Max Kellermann <max@duempel.org> | 2010-08-06 22:18:01 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2010-08-31 06:49:06 +0200 |
commit | a77506ae215df09ed02c30f39a3be663a3180d5b (patch) | |
tree | 3e3bc932f7d78721285a51b7c260576eb323ef91 | |
parent | ed5d297301ad07e1c8f59b25184b4148046c1ebe (diff) | |
download | mpd-a77506ae215df09ed02c30f39a3be663a3180d5b.tar.gz mpd-a77506ae215df09ed02c30f39a3be663a3180d5b.tar.xz mpd-a77506ae215df09ed02c30f39a3be663a3180d5b.zip |
output/httpd: forced flush after 32 kB of input data
Avoid buffer underruns on the streaming client, if the encoder is "too
efficient" (e.g. when encoding silence while paused).
-rw-r--r-- | src/output/httpd_internal.h | 8 | ||||
-rw-r--r-- | src/output/httpd_output_plugin.c | 15 |
2 files changed, 23 insertions, 0 deletions
diff --git a/src/output/httpd_internal.h b/src/output/httpd_internal.h index 55843e73f..14a5cf350 100644 --- a/src/output/httpd_internal.h +++ b/src/output/httpd_internal.h @@ -52,6 +52,14 @@ struct httpd_output { struct encoder *encoder; /** + * Number of bytes which were fed into the encoder, without + * ever receiving new output. This is used to estimate + * whether MPD should manually flush the encoder, to avoid + * buffer underruns in the client. + */ + size_t unflushed_input; + + /** * The MIME type produced by the #encoder. */ const char *content_type; diff --git a/src/output/httpd_output_plugin.c b/src/output/httpd_output_plugin.c index 140ea7d82..a71e21604 100644 --- a/src/output/httpd_output_plugin.c +++ b/src/output/httpd_output_plugin.c @@ -262,12 +262,22 @@ httpd_output_read_page(struct httpd_output *httpd) { size_t size = 0, nbytes; + if (httpd->unflushed_input >= 65536) { + /* we have fed a lot of input into the encoder, but it + didn't give anything back yet - flush now to avoid + buffer underruns */ + encoder_flush(httpd->encoder, NULL); + httpd->unflushed_input = 0; + } + do { nbytes = encoder_read(httpd->encoder, httpd->buffer + size, sizeof(httpd->buffer) - size); if (nbytes == 0) break; + httpd->unflushed_input = 0; + size += nbytes; } while (size < sizeof(httpd->buffer)); @@ -292,6 +302,9 @@ httpd_output_encoder_open(struct httpd_output *httpd, bytes of encoder output after opening it, because it has to be sent to every new client */ httpd->header = httpd_output_read_page(httpd); + + httpd->unflushed_input = 0; + return true; } @@ -451,6 +464,8 @@ httpd_output_encode_and_play(struct httpd_output *httpd, if (!success) return false; + httpd->unflushed_input += size; + httpd_output_encoder_to_clients(httpd); return true; |