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).
This commit is contained in:
parent
ed5d297301
commit
a77506ae21
@ -51,6 +51,14 @@ struct httpd_output {
|
|||||||
*/
|
*/
|
||||||
struct encoder *encoder;
|
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.
|
* The MIME type produced by the #encoder.
|
||||||
*/
|
*/
|
||||||
|
@ -262,12 +262,22 @@ httpd_output_read_page(struct httpd_output *httpd)
|
|||||||
{
|
{
|
||||||
size_t size = 0, nbytes;
|
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 {
|
do {
|
||||||
nbytes = encoder_read(httpd->encoder, httpd->buffer + size,
|
nbytes = encoder_read(httpd->encoder, httpd->buffer + size,
|
||||||
sizeof(httpd->buffer) - size);
|
sizeof(httpd->buffer) - size);
|
||||||
if (nbytes == 0)
|
if (nbytes == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
httpd->unflushed_input = 0;
|
||||||
|
|
||||||
size += nbytes;
|
size += nbytes;
|
||||||
} while (size < sizeof(httpd->buffer));
|
} 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
|
bytes of encoder output after opening it, because it has to
|
||||||
be sent to every new client */
|
be sent to every new client */
|
||||||
httpd->header = httpd_output_read_page(httpd);
|
httpd->header = httpd_output_read_page(httpd);
|
||||||
|
|
||||||
|
httpd->unflushed_input = 0;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,6 +464,8 @@ httpd_output_encode_and_play(struct httpd_output *httpd,
|
|||||||
if (!success)
|
if (!success)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
httpd->unflushed_input += size;
|
||||||
|
|
||||||
httpd_output_encoder_to_clients(httpd);
|
httpd_output_encoder_to_clients(httpd);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user