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).
Diffstat (limited to '')
-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; |