Commit ae38332e authored by Joseph Wallace's avatar Joseph Wallace Committed by Philipp Schafft
Browse files

Implement output buffering for webm filter.

parent 94ce64d4
......@@ -65,6 +65,10 @@ typedef struct _webm_t {
static int send_webm(shout_t *self, const unsigned char *data, size_t len);
static void close_webm(shout_t *self);
static size_t copy_possible(const void *src, size_t srcLen,
void *target, size_t targetLen);
static int flush_output(shout_t *self, webm_t *webm);
/* -- interface functions -- */
int shout_open_webm(shout_t *self)
{
......@@ -86,13 +90,28 @@ int shout_open_webm(shout_t *self)
static int send_webm(shout_t *self, const unsigned char *data, size_t len)
{
webm_t *webm = (webm_t *) self->format_data;
/* IMPORTANT TODO: we just send the raw data. We need throttling. */
ssize_t ret = shout_send_raw(self, data, len);
if (ret != (ssize_t)len)
return self->error = SHOUTERR_SOCKET;
size_t copied = 0;
unsigned const char *src = data;
unsigned char *target;
size_t target_space;
return self->error = SHOUTERR_SUCCESS;
self->error = SHOUTERR_SUCCESS;
while(len > 0 && self->error == SHOUTERR_SUCCESS) {
target = webm->output_buffer + webm->output_position;
target_space = SHOUT_BUFSIZE - webm->output_position;
copied = copy_possible(src, len, target, target_space);
src += copied;
webm->output_position += copied;
len -= copied;
self->error = flush_output(self, webm);
}
return self->error;
}
static void close_webm(shout_t *self)
......@@ -100,3 +119,43 @@ static void close_webm(shout_t *self)
webm_t *webm_filter = (webm_t *) self->format_data;
if(webm_filter) free(webm_filter);
}
/* -- utility functions -- */
/* Copies as much of the source buffer into the target
* as will fit, and returns the actual size copied.
*/
static size_t copy_possible(const void *src, size_t srcLen,
void *target, size_t targetLen)
{
size_t to_copy = srcLen;
if(targetLen < to_copy) to_copy = targetLen;
memcpy(target, src, to_copy);
return to_copy;
}
/* Send currently buffered output to the server.
* Output buffering is needed because parsing
* and/or rewriting code may pass through small
* chunks at a time, and we don't want to expend a
* syscall on each one.
* However, we do not want to leave sendable data
* in the buffer before we return to the client and
* potentially sleep, so this is called before
* send_webm() returns.
*/
static int flush_output(shout_t *self, webm_t *webm)
{
if(webm->output_position == 0) {
return self->error = SHOUTERR_SUCCESS;
}
ssize_t ret = shout_send_raw(self, webm->output_buffer, webm->output_position);
if (ret != (ssize_t) webm->output_position) {
return self->error = SHOUTERR_SOCKET;
}
webm->output_position = 0;
return self->error = SHOUTERR_SUCCESS;
}
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