Commit 9c44a7d1 authored by Karl Heyes's avatar Karl Heyes

merged singleq branch 7177:7591

svn path=/icecast/trunk/icecast/; revision=7592
parent 490e6466
......@@ -799,11 +799,7 @@ static void command_metadata(client_t *client, source_t *source)
state = source->format->_state;
thread_mutex_lock(&(state->lock));
free(state->metadata);
state->metadata = strdup(value);
state->metadata_age++;
thread_mutex_unlock(&(state->lock));
mp3_set_tag (source->format, "title", value);
DEBUG2("Metadata on mountpoint %s changed to \"%s\"",
source->mount, value);
......
......@@ -339,7 +339,8 @@ static void _set_defaults(ice_config_t *configuration)
configuration->num_yp_directories = 0;
configuration->relay_username = NULL;
configuration->relay_password = NULL;
configuration->burst_on_connect = 1;
/* default to a typical prebuffer size used by clients */
configuration->burst_size = 65536;
}
static void _parse_root(xmlDocPtr doc, xmlNodePtr node,
......@@ -463,7 +464,12 @@ static void _parse_limits(xmlDocPtr doc, xmlNodePtr node,
if (tmp) xmlFree(tmp);
} else if (strcmp(node->name, "burst-on-connect") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->burst_on_connect = atoi(tmp);
if (atoi(tmp) == 0)
configuration->burst_size = 0;
if (tmp) xmlFree(tmp);
} else if (strcmp(node->name, "burst-size") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->burst_size = atoi(tmp);
if (tmp) xmlFree(tmp);
}
} while ((node = node->next));
......@@ -489,7 +495,9 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
else
configuration->mounts = mount;
/* default <mount> settings */
mount->max_listeners = -1;
mount->burst_size = -1;
mount->next = NULL;
do {
......@@ -574,6 +582,10 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
mount->source_timeout = atoi (tmp);
xmlFree(tmp);
}
} else if (strcmp(node->name, "burst-size") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
mount->burst_size = atoi(tmp);
if (tmp) xmlFree(tmp);
}
} while ((node = node->next));
}
......
......@@ -54,8 +54,10 @@ typedef struct _mount_proxy {
clients from the fallback? */
int no_mount; /* Do we permit direct requests of this mountpoint? (or only
indirect, through fallbacks) */
unsigned queue_size_limit;
unsigned source_timeout; /* source timeout in seconds */
int burst_size; /* amount to send to a new client if possible, -1 take
* from global setting */
unsigned int queue_size_limit;
unsigned int source_timeout; /* source timeout in seconds */
char *auth_type; /* Authentication type */
config_options_t *auth_options; /* Options for this type */
......@@ -84,8 +86,9 @@ typedef struct ice_config_tag
int client_limit;
int source_limit;
unsigned queue_size_limit;
unsigned int queue_size_limit;
int threadpool_size;
unsigned int burst_size;
int client_timeout;
int header_timeout;
int source_timeout;
......@@ -133,7 +136,6 @@ typedef struct ice_config_tag
char *yp_url[MAX_YP_DIRECTORIES];
int yp_url_timeout[MAX_YP_DIRECTORIES];
int num_yp_directories;
int burst_on_connect;
} ice_config_t;
typedef struct {
......
......@@ -42,17 +42,14 @@ client_t *client_create(connection_t *con, http_parser_t *parser)
client->con = con;
client->parser = parser;
client->queue = NULL;
client->refbuf = NULL;
client->pos = 0;
client->burst_sent = 0;
return client;
}
void client_destroy(client_t *client)
{
refbuf_t *refbuf;
if (client == NULL)
return;
/* write log entry if ip is set (some things don't set it, like outgoing
......@@ -64,9 +61,9 @@ void client_destroy(client_t *client)
connection_close(client->con);
httpp_destroy(client->parser);
while ((refbuf = refbuf_queue_remove(&client->queue)))
refbuf_release(refbuf);
/* drop ref counts if need be */
if (client->refbuf)
refbuf_release (client->refbuf);
/* we need to free client specific format data (if any) */
if (client->free_client_data)
client->free_client_data (client);
......@@ -144,3 +141,14 @@ int client_send_bytes (client_t *client, const void *buf, unsigned len)
return ret;
}
void client_set_queue (client_t *client, refbuf_t *refbuf)
{
refbuf_t *to_release = client->refbuf;
client->refbuf = refbuf;
refbuf_addref (client->refbuf);
client->pos = 0;
if (to_release)
refbuf_release (to_release);
}
......@@ -32,8 +32,9 @@ typedef struct _client_tag
/* http response code for this client */
int respcode;
/* buffer queue */
refbuf_queue_t *queue;
/* where in the queue the client is */
refbuf_t *refbuf;
/* position in first buffer */
unsigned long pos;
......@@ -45,7 +46,6 @@ typedef struct _client_tag
/* function to call to release format specific resources */
void (*free_client_data)(struct _client_tag *client);
int burst_sent;
} client_t;
client_t *client_create(connection_t *con, http_parser_t *parser);
......@@ -56,5 +56,6 @@ void client_send_401(client_t *client);
void client_send_403(client_t *client);
void client_send_400(client_t *client, char *message);
int client_send_bytes (client_t *client, const void *buf, unsigned len);
void client_set_queue (client_t *client, refbuf_t *refbuf);
#endif /* __CLIENT_H__ */
......@@ -465,9 +465,8 @@ int connection_complete_source (source_t *source)
"for icecast 1.x relays. Assuming content is mp3.");
format_type = FORMAT_TYPE_MP3;
}
source->format = format_get_plugin (format_type, source->mount, source->parser);
if (source->format == NULL)
if (format_get_plugin (format_type, source) < 0)
{
global_unlock();
config_release_config();
......@@ -483,6 +482,7 @@ int connection_complete_source (source_t *source)
/* set global settings first */
source->queue_size_limit = config->queue_size_limit;
source->timeout = config->source_timeout;
source->burst_size = config->burst_size;
/* for relays, we don't yet have a client, however we do require one
* to retrieve the stream from. This is created here, quite late,
......@@ -932,8 +932,7 @@ static void _handle_get_request(connection_t *con,
global.clients++;
global_unlock();
client->format_data = source->format->create_client_data(
source->format, source, client);
source->format->create_client_data (source, client);
source->format->client_send_headers(source->format, source, client);
......
......@@ -75,32 +75,22 @@ char *format_get_mimetype(format_type_t type)
}
}
format_plugin_t *format_get_plugin(format_type_t type, char *mount,
http_parser_t *parser)
int format_get_plugin(format_type_t type, source_t *source)
{
format_plugin_t *plugin;
int ret = -1;
switch (type) {
case FORMAT_TYPE_VORBIS:
plugin = format_vorbis_get_plugin();
if (plugin) plugin->mount = mount;
ret = format_vorbis_get_plugin (source);
break;
case FORMAT_TYPE_MP3:
plugin = format_mp3_get_plugin(parser);
if (plugin) plugin->mount = mount;
ret = format_mp3_get_plugin (source);
break;
default:
plugin = NULL;
break;
}
return plugin;
}
int format_generic_write_buf_to_client(format_plugin_t *format,
client_t *client, unsigned char *buf, int len)
{
return client_send_bytes (client, buf, len);
return ret;
}
void format_send_general_headers(format_plugin_t *format,
......
......@@ -45,13 +45,10 @@ typedef struct _format_plugin_tag
*/
int has_predata;
int (*get_buffer)(struct _format_plugin_tag *self, char *data, unsigned long
len, refbuf_t **buffer);
refbuf_queue_t *(*get_predata)(struct _format_plugin_tag *self);
int (*write_buf_to_client)(struct _format_plugin_tag *format,
client_t *client, unsigned char *buf, int len);
void *(*create_client_data)(struct _format_plugin_tag *format,
struct source_tag *source, client_t *client);
refbuf_t *(*get_buffer)(struct source_tag *);
int (*write_buf_to_client)(struct _format_plugin_tag *format, client_t *client);
void (*write_buf_to_file)(struct source_tag *source, refbuf_t *refbuf);
int (*create_client_data)(struct source_tag *source, client_t *client);
void (*client_send_headers)(struct _format_plugin_tag *format,
struct source_tag *source, client_t *client);
void (*free_plugin)(struct _format_plugin_tag *self);
......@@ -62,11 +59,8 @@ typedef struct _format_plugin_tag
format_type_t format_get_type(char *contenttype);
char *format_get_mimetype(format_type_t type);
format_plugin_t *format_get_plugin(format_type_t type, char *mount,
http_parser_t *parser);
int format_get_plugin(format_type_t type, struct source_tag *source);
int format_generic_write_buf_to_client(format_plugin_t *format,
client_t *client, unsigned char *buf, int len);
void format_send_general_headers(format_plugin_t *format,
struct source_tag *source, client_t *client);
......
This diff is collapsed.
......@@ -19,18 +19,23 @@
#define __FORMAT_MP3_H__
typedef struct {
char *metadata;
int metadata_age;
mutex_t lock;
/* These are for inline metadata */
int inline_metadata_interval;
int offset;
int metadata_length;
char *metadata_buffer;
int metadata_offset;
unsigned interval;
char *url_artist;
char *url_title;
int update_metadata;
refbuf_t *metadata;
mutex_t url_lock;
unsigned build_metadata_len;
unsigned build_metadata_offset;
char build_metadata[4081];
} mp3_state;
format_plugin_t *format_mp3_get_plugin(http_parser_t *parser);
int format_mp3_get_plugin(struct source_tag *src);
void mp3_set_tag (format_plugin_t *plugin, char *tag, char *value);
#endif /* __FORMAT_MP3_H__ */
This diff is collapsed.
......@@ -18,6 +18,6 @@
#ifndef __FORMAT_VORBIS_H__
#define __FORMAT_VORBIS_H__
format_plugin_t *format_vorbis_get_plugin(void);
int format_vorbis_get_plugin(source_t *source);
#endif /* __FORMAT_VORBIS_H__ */
......@@ -38,9 +38,22 @@ refbuf_t *refbuf_new(unsigned long size)
refbuf_t *refbuf;
refbuf = (refbuf_t *)malloc(sizeof(refbuf_t));
refbuf->data = (void *)malloc(size);
if (refbuf == NULL)
return NULL;
refbuf->data = NULL;
if (size)
{
refbuf->data = malloc (size);
if (refbuf->data == NULL)
{
free (refbuf);
return NULL;
}
}
refbuf->len = size;
refbuf->_count = 1;
refbuf->next = NULL;
refbuf->associated = NULL;
return refbuf;
}
......@@ -54,100 +67,15 @@ void refbuf_release(refbuf_t *self)
{
self->_count--;
if (self->_count == 0) {
while (self->associated)
{
refbuf_t *ref = self->associated;
self->associated = ref->next;
refbuf_release (ref);
}
free(self->data);
free(self);
return;
}
}
void refbuf_queue_add(refbuf_queue_t **queue, refbuf_t *refbuf)
{
refbuf_queue_t *node;
refbuf_queue_t *item = (refbuf_queue_t *)malloc(sizeof(refbuf_queue_t));
item->refbuf = refbuf;
item->next = NULL;
if (*queue == NULL) {
*queue = item;
(*queue)->total_length = item->refbuf->len;
} else {
node = *queue;
while (node->next) node = node->next;
node->next = item;
(*queue)->total_length += item->refbuf->len;
}
}
refbuf_t *refbuf_queue_remove(refbuf_queue_t **queue)
{
refbuf_queue_t *item;
refbuf_t *refbuf;
if (*queue == NULL) return NULL;
item = *queue;
*queue = item->next;
item->next = NULL;
refbuf = item->refbuf;
item->refbuf = NULL;
if(*queue)
(*queue)->total_length = item->total_length - refbuf->len;
free(item);
return refbuf;
}
refbuf_t * refbuf_queue_get(refbuf_queue_t **queue, int item)
{
refbuf_queue_t *node = *queue;
int size = 0;
while (node) {
if (size == item) {
return node->refbuf;
}
node = node->next;
size++;
}
return NULL;
}
void refbuf_queue_insert(refbuf_queue_t **queue, refbuf_t *refbuf)
{
refbuf_queue_t *item = (refbuf_queue_t *)malloc(sizeof(refbuf_queue_t));
item->refbuf = refbuf;
item->next = *queue;
if(item->next)
item->total_length = item->next->total_length + item->refbuf->len;
else
item->total_length = item->refbuf->len;
*queue = item;
}
int refbuf_queue_size(refbuf_queue_t **queue)
{
refbuf_queue_t *node = *queue;
int size = 0;
while (node) {
node = node->next;
size++;
}
return size;
}
int refbuf_queue_length(refbuf_queue_t **queue)
{
if(*queue)
return (*queue)->total_length;
else
return 0;
}
......@@ -22,18 +22,12 @@ typedef struct _refbuf_tag
{
char *data;
long len;
struct _refbuf_tag *associated;
struct _refbuf_tag *next;
unsigned long _count;
} refbuf_t;
typedef struct _refbuf_queue_tag
{
refbuf_t *refbuf;
long total_length;
struct _refbuf_queue_tag *next;
} refbuf_queue_t;
void refbuf_initialize(void);
void refbuf_shutdown(void);
......@@ -41,22 +35,5 @@ refbuf_t *refbuf_new(unsigned long size);
void refbuf_addref(refbuf_t *self);
void refbuf_release(refbuf_t *self);
void refbuf_queue_add(refbuf_queue_t **queue, refbuf_t *refbuf);
refbuf_t *refbuf_queue_remove(refbuf_queue_t **queue);
void refbuf_queue_insert(refbuf_queue_t **queue, refbuf_t *refbuf);
/* Size in buffers */
int refbuf_queue_size(refbuf_queue_t **queue);
/* Size in bytes */
int refbuf_queue_length(refbuf_queue_t **queue);
refbuf_t * refbuf_queue_get(refbuf_queue_t **queue, int item);
#endif /* __REFBUF_H__ */
This diff is collapsed.
......@@ -55,11 +55,22 @@ typedef struct source_tag
struct auth_tag *authenticator;
int fallback_override;
int no_mount;
unsigned queue_size_limit;
/* per source burst handling for connecting clients */
unsigned int burst_size; /* trigger level for burst on connect */
unsigned int burst_offset;
refbuf_t *burst_point;
unsigned int queue_size;
unsigned int queue_size_limit;
unsigned timeout; /* source timeout in seconds */
refbuf_queue_t *queue;
mutex_t queue_mutex;
int burst_on_connect;
time_t last_read;
int short_delay;
refbuf_t *stream_data;
refbuf_t *stream_data_tail;
} source_t;
source_t *source_reserve (const char *mount);
......
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