mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
Two things:
1) vorbis tags (ARTIST and TITLE) now appear in the stats. Oddsock did the first cut of this. 2) stats bug fixed. if a stats value was NULL a segfault occurred. strdup(NULL) is fun! svn path=/trunk/icecast/; revision=3024
This commit is contained in:
parent
0512d524e4
commit
c7aa89cf26
@ -15,13 +15,14 @@
|
||||
|
||||
#include "format_vorbis.h"
|
||||
|
||||
format_plugin_t *format_get_plugin(format_type_t type)
|
||||
format_plugin_t *format_get_plugin(format_type_t type, char *mount)
|
||||
{
|
||||
format_plugin_t *plugin;
|
||||
|
||||
switch (type) {
|
||||
case FORMAT_TYPE_VORBIS:
|
||||
plugin = format_vorbis_get_plugin();
|
||||
if (plugin) plugin->mount = mount;
|
||||
break;
|
||||
default:
|
||||
plugin = NULL;
|
||||
|
@ -16,6 +16,9 @@ typedef struct _format_plugin_tag
|
||||
{
|
||||
format_type_t type;
|
||||
|
||||
/* we need to know the mount to report statistics */
|
||||
char *mount;
|
||||
|
||||
/* set this is the data format has a header that
|
||||
** we must send before regular data
|
||||
*/
|
||||
@ -29,7 +32,7 @@ typedef struct _format_plugin_tag
|
||||
void *_state;
|
||||
} format_plugin_t;
|
||||
|
||||
format_plugin_t *format_get_plugin(format_type_t type);
|
||||
format_plugin_t *format_get_plugin(format_type_t type, char *mount);
|
||||
|
||||
#endif /* __FORMAT_H__ */
|
||||
|
||||
|
@ -18,10 +18,15 @@
|
||||
typedef struct _vstate_tag
|
||||
{
|
||||
ogg_sync_state oy;
|
||||
ogg_stream_state os;
|
||||
vorbis_info vi;
|
||||
vorbis_comment vc;
|
||||
|
||||
ogg_page og;
|
||||
unsigned long serialno;
|
||||
int header;
|
||||
refbuf_t *headbuf[10];
|
||||
int packets;
|
||||
} vstate_t;
|
||||
|
||||
void format_vorbis_free_plugin(format_plugin_t *self);
|
||||
@ -58,6 +63,9 @@ void format_vorbis_free_plugin(format_plugin_t *self)
|
||||
|
||||
/* free state memory */
|
||||
ogg_sync_clear(&state->oy);
|
||||
ogg_stream_clear(&state->os);
|
||||
vorbis_comment_clear(&state->vc);
|
||||
vorbis_info_clear(&state->vi);
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (state->headbuf[i]) {
|
||||
@ -76,7 +84,9 @@ refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned l
|
||||
{
|
||||
char *buffer;
|
||||
refbuf_t *refbuf;
|
||||
int i;
|
||||
int i, result;
|
||||
ogg_packet op;
|
||||
char *tag;
|
||||
vstate_t *state = (vstate_t *)self->_state;
|
||||
|
||||
if (data) {
|
||||
@ -95,6 +105,9 @@ refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned l
|
||||
if (state->serialno != ogg_page_serialno(&state->og)) {
|
||||
/* this is a new logical bitstream */
|
||||
state->header = 0;
|
||||
state->packets = 0;
|
||||
|
||||
/* release old headers, stream state, vorbis data */
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (state->headbuf[i]) {
|
||||
refbuf_release(state->headbuf[i]);
|
||||
@ -103,20 +116,56 @@ refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned l
|
||||
}
|
||||
|
||||
state->serialno = ogg_page_serialno(&state->og);
|
||||
ogg_stream_init(&state->os, state->serialno);
|
||||
vorbis_info_init(&state->vi);
|
||||
vorbis_comment_init(&state->vc);
|
||||
}
|
||||
|
||||
if (state->header >= 0) {
|
||||
if (ogg_page_granulepos(&state->og) == 0) {
|
||||
state->header++;
|
||||
} else {
|
||||
state->header = 0;
|
||||
/* we're done caching headers */
|
||||
state->header = -1;
|
||||
|
||||
/* put known comments in the stats */
|
||||
tag = vorbis_comment_query(&state->vc, "TITLE", 0);
|
||||
if (tag) stats_event_args(self->mount, "title", tag);
|
||||
else stats_event_args(self->mount, "title", "unknown");
|
||||
tag = vorbis_comment_query(&state->vc, "ARTIST", 0);
|
||||
if (tag) stats_event_args(self->mount, "artist", tag);
|
||||
else stats_event_args(self->mount, "artist", "unknown");
|
||||
|
||||
/* don't need these now */
|
||||
ogg_stream_clear(&state->os);
|
||||
vorbis_comment_clear(&state->vc);
|
||||
vorbis_info_clear(&state->vi);
|
||||
}
|
||||
}
|
||||
|
||||
/* cache first three pages */
|
||||
if (state->header) {
|
||||
/* cache header pages */
|
||||
if (state->header > 0) {
|
||||
refbuf_addref(refbuf);
|
||||
state->headbuf[state->header - 1] = refbuf;
|
||||
|
||||
if (state->packets >= 0 && state->packets < 2) {
|
||||
ogg_stream_pagein(&state->os, &state->og);
|
||||
while (state->packets < 2) {
|
||||
result = ogg_stream_packetout(&state->os, &op);
|
||||
if (result == 0) break; /* need more data */
|
||||
if (result < 0) {
|
||||
state->packets = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
state->packets++;
|
||||
|
||||
if (vorbis_synthesis_headerin(&state->vi, &state->vc, &op) < 0) {
|
||||
state->packets = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
13
src/source.c
13
src/source.c
@ -41,10 +41,10 @@ source_t *source_create(connection_t *con, http_parser_t *parser, const char *mo
|
||||
source_t *src;
|
||||
|
||||
src = (source_t *)malloc(sizeof(source_t));
|
||||
src->format = format_get_plugin(type);
|
||||
src->mount = (char *)strdup(mount);
|
||||
src->format = format_get_plugin(type, src->mount);
|
||||
src->con = con;
|
||||
src->parser = parser;
|
||||
src->mount = (char *)strdup(mount);
|
||||
src->client_tree = avl_tree_new(_compare_clients, NULL);
|
||||
src->pending_tree = avl_tree_new(_compare_clients, NULL);
|
||||
|
||||
@ -110,6 +110,7 @@ void *source_main(void *arg)
|
||||
int ret, timeout;
|
||||
client_t *client;
|
||||
avl_node *client_node;
|
||||
char *s;
|
||||
|
||||
refbuf_t *refbuf, *abuf;
|
||||
int data_done;
|
||||
@ -134,6 +135,14 @@ void *source_main(void *arg)
|
||||
|
||||
/* start off the statistics */
|
||||
stats_event(source->mount, "listeners", "0");
|
||||
if ((s = httpp_getvar(source->parser, "ice-name")))
|
||||
stats_event(source->mount, "name", s);
|
||||
if ((s = httpp_getvar(source->parser, "ice-url")))
|
||||
stats_event(source->mount, "url", s);
|
||||
if ((s = httpp_getvar(source->parser, "ice-bitrate")))
|
||||
stats_event(source->mount, "bitrate", s);
|
||||
if ((s = httpp_getvar(source->parser, "ice-description")))
|
||||
stats_event(source->mount, "description", s);
|
||||
|
||||
while (global.running == ICE_RUNNING) {
|
||||
refbuf = source->format->get_buffer(source->format, NULL, 0);
|
||||
|
@ -286,7 +286,10 @@ static stats_event_t *_copy_event(stats_event_t *event)
|
||||
else
|
||||
copy->source = NULL;
|
||||
copy->name = (char *)strdup(event->name);
|
||||
copy->value = (char *)strdup(event->value);
|
||||
if (event->value)
|
||||
copy->value = (char *)strdup(event->value);
|
||||
else
|
||||
copy->value = NULL;
|
||||
copy->next = NULL;
|
||||
|
||||
return copy;
|
||||
@ -480,7 +483,7 @@ static int _send_event_to_client(stats_event_t *event, connection_t *con)
|
||||
int ret;
|
||||
|
||||
/* send data to the client!!!! */
|
||||
ret = sock_write(con->sock, "EVENT %s %s %s\n", (event->source != NULL) ? event->source : "global", event->name, event->value);
|
||||
ret = sock_write(con->sock, "EVENT %s %s %s\n", (event->source != NULL) ? event->source : "global", event->name, event->value ? event->value : "null");
|
||||
|
||||
return (ret == -1) ? 0 : 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user