Commit a77506ae authored by Max Kellermann's avatar Max Kellermann

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).
parent ed5d2973
......@@ -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;
......
......@@ -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;
......
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