[xiph-commits] r15622 - icecast/trunk/icecast/src
karl at svn.xiph.org
karl at svn.xiph.org
Wed Jan 14 19:38:50 PST 2009
Author: karl
Date: 2009-01-14 19:38:49 -0800 (Wed, 14 Jan 2009)
New Revision: 15622
Modified:
icecast/trunk/icecast/src/admin.c
icecast/trunk/icecast/src/format_mp3.c
icecast/trunk/icecast/src/format_mp3.h
icecast/trunk/icecast/src/format_vorbis.c
Log:
explicitly flag up a metadata update after they have been set. Could of led to
a non-crash type race between artist and title fields updating. Also allow
passing a url setting, mapping to StreamURL in the icy metadata block, but do
not override any existing inline setting.
Modified: icecast/trunk/icecast/src/admin.c
===================================================================
--- icecast/trunk/icecast/src/admin.c 2009-01-14 01:18:22 UTC (rev 15621)
+++ icecast/trunk/icecast/src/admin.c 2009-01-15 03:38:49 UTC (rev 15622)
@@ -941,6 +941,8 @@
source->mount, artist, title);
}
}
+ /* updates are now done, let them be pushed into the stream */
+ plugin->set_tag (plugin, NULL, NULL, NULL);
}
else
{
@@ -983,6 +985,7 @@
if (same_ip && source->format && source->format->set_tag)
{
source->format->set_tag (source->format, "title", value, NULL);
+ source->format->set_tag (source->format, NULL, NULL, NULL);
DEBUG2("Metadata on mountpoint %s changed to \"%s\"",
source->mount, value);
Modified: icecast/trunk/icecast/src/format_mp3.c
===================================================================
--- icecast/trunk/icecast/src/format_mp3.c 2009-01-14 01:18:22 UTC (rev 15621)
+++ icecast/trunk/icecast/src/format_mp3.c 2009-01-15 03:38:49 UTC (rev 15622)
@@ -127,38 +127,40 @@
static void mp3_set_tag (format_plugin_t *plugin, const char *tag, const char *in_value, const char *charset)
{
mp3_state *source_mp3 = plugin->_state;
- unsigned int len;
- const char meta[] = "StreamTitle='";
- int size = sizeof (meta) + 1;
- char *value;
+ char *value = NULL;
- if (tag==NULL || in_value == NULL)
- return;
-
/* protect against multiple updaters */
thread_mutex_lock (&source_mp3->url_lock);
- value = util_conv_string (in_value, charset, plugin->charset);
- if (value == NULL)
- value = strdup (in_value);
+ if (tag==NULL)
+ {
+ source_mp3->update_metadata = 1;
+ thread_mutex_unlock (&source_mp3->url_lock);
+ return;
+ }
- len = strlen (value)+1;
- size += len;
+ if (in_value)
+ {
+ value = util_conv_string (in_value, charset, plugin->charset);
+ if (value == NULL)
+ value = strdup (in_value);
+ }
if (strcmp (tag, "title") == 0 || strcmp (tag, "song") == 0)
{
free (source_mp3->url_title);
- free (source_mp3->url_artist);
- source_mp3->url_artist = NULL;
source_mp3->url_title = value;
- source_mp3->update_metadata = 1;
}
else if (strcmp (tag, "artist") == 0)
{
free (source_mp3->url_artist);
source_mp3->url_artist = value;
- source_mp3->update_metadata = 1;
}
+ else if (strcmp (tag, "url") == 0)
+ {
+ free (source_mp3->url);
+ source_mp3->url = value;
+ }
else
free (value);
thread_mutex_unlock (&source_mp3->url_lock);
@@ -234,11 +236,12 @@
*/
static void mp3_set_title (source_t *source)
{
- const char meta[] = "StreamTitle='";
- int size;
+ const char streamtitle[] = "StreamTitle='";
+ const char streamurl[] = "StreamUrl='";
+ size_t size;
unsigned char len_byte;
refbuf_t *p;
- unsigned int len = sizeof(meta) + 2; /* the StreamTitle, quotes, ; and null */
+ unsigned int len = sizeof(streamtitle) + 2; /* the StreamTitle, quotes, ; and null */
mp3_state *source_mp3 = source->format->_state;
/* make sure the url data does not disappear from under us */
@@ -251,6 +254,14 @@
len += strlen (source_mp3->url_title);
if (source_mp3->url_artist && source_mp3->url_title)
len += 3;
+ if (source_mp3->inline_url)
+ {
+ char *end = strstr (source_mp3->inline_url, "';");
+ if (end)
+ len += end - source_mp3->inline_url+2;
+ }
+ else if (source_mp3->url)
+ len += strlen (source_mp3->url) + strlen (streamurl) + 2;
#define MAX_META_LEN 255*16
if (len > MAX_META_LEN)
{
@@ -268,14 +279,29 @@
if (p)
{
mp3_state *source_mp3 = source->format->_state;
+ int r;
memset (p->data, '\0', size);
if (source_mp3->url_artist && source_mp3->url_title)
- snprintf (p->data, size, "%c%s%s - %s';", len_byte, meta,
+ r = snprintf (p->data, size, "%c%s%s - %s';", len_byte, streamtitle,
source_mp3->url_artist, source_mp3->url_title);
else
- snprintf (p->data, size, "%c%s%s';", len_byte, meta,
+ r = snprintf (p->data, size, "%c%s%s';", len_byte, streamtitle,
source_mp3->url_title);
+ if (r > 0)
+ {
+ if (source_mp3->inline_url)
+ {
+ char *end = strstr (source_mp3->inline_url, "';");
+ int urllen = size;
+ if (end) urllen = end - source_mp3->inline_url + 2;
+ if (size-r > urllen)
+ snprintf (p->data+r, size-r, "StreamUrl='%s';", source_mp3->inline_url+11);
+ }
+ else if (source_mp3->url)
+ snprintf (p->data+r, size-r, "StreamUrl='%s';", source_mp3->url);
+ }
+ DEBUG1 ("shoutcast metadata block setup with %s", p->data+1);
filter_shoutcast_metadata (source, p->data, size);
refbuf_release (source_mp3->metadata);
@@ -289,7 +315,7 @@
* which is 0 or greater. Check the client in_metadata value afterwards
* to see if all metadata has been sent
*/
-static int send_mp3_metadata (client_t *client, refbuf_t *associated)
+static int send_stream_metadata (client_t *client, refbuf_t *associated)
{
int ret = 0;
char *metadata;
@@ -355,7 +381,7 @@
if (client_mp3->in_metadata)
{
refbuf_t *associated = refbuf->associated;
- ret = send_mp3_metadata (client, associated);
+ ret = send_stream_metadata (client, associated);
if (client_mp3->in_metadata)
break;
@@ -367,7 +393,7 @@
unsigned int remaining = client_mp3->interval -
client_mp3->since_meta_block;
- /* sending the metadata block */
+ /* leading up to sending the metadata block */
if (remaining <= len)
{
/* send any mp3 before the metadata block */
@@ -384,11 +410,10 @@
break;
written += ret;
}
- ret = send_mp3_metadata (client, refbuf->associated);
+ ret = send_stream_metadata (client, refbuf->associated);
if (client_mp3->in_metadata)
break;
written += ret;
- /* change buf and len */
buf += remaining;
len -= remaining;
/* limit how much mp3 we send if using small intervals */
@@ -602,6 +627,7 @@
source_mp3->build_metadata_len);
refbuf_release (source_mp3->metadata);
source_mp3->metadata = meta;
+ source_mp3->inline_url = strstr (meta->data+1, "StreamUrl='");
}
else
{
@@ -633,7 +659,7 @@
{
mp3_client_data *client_mp3 = calloc(1,sizeof(mp3_client_data));
mp3_state *source_mp3 = source->format->_state;
- const char *metadata;
+ const char *metadata;
/* the +-2 is for overwriting the last set of \r\n */
unsigned remaining = 4096 - client->refbuf->len + 2;
char *ptr = client->refbuf->data + client->refbuf->len - 2;
Modified: icecast/trunk/icecast/src/format_mp3.h
===================================================================
--- icecast/trunk/icecast/src/format_mp3.h 2009-01-14 01:18:22 UTC (rev 15621)
+++ icecast/trunk/icecast/src/format_mp3.h 2009-01-15 03:38:49 UTC (rev 15622)
@@ -25,11 +25,13 @@
int interval;
char *url_artist;
char *url_title;
+ char *url;
+ char *inline_url;
int update_metadata;
refbuf_t *metadata;
refbuf_t *read_data;
- unsigned int read_count;
+ int read_count;
mutex_t url_lock;
unsigned build_metadata_len;
Modified: icecast/trunk/icecast/src/format_vorbis.c
===================================================================
--- icecast/trunk/icecast/src/format_vorbis.c 2009-01-14 01:18:22 UTC (rev 15621)
+++ icecast/trunk/icecast/src/format_vorbis.c 2009-01-15 03:38:49 UTC (rev 15622)
@@ -421,7 +421,6 @@
ogg_state_t *ogg_info = plugin->_state;
ogg_codec_t *codec = ogg_info->codecs;
vorbis_codec_t *source_vorbis;
- int change = 0;
char *value;
/* avoid updating if multiple codecs in use */
@@ -430,6 +429,13 @@
else
return;
+ if (tag == NULL)
+ {
+ source_vorbis->stream_notify = 1;
+ source_vorbis->rebuild_comment = 1;
+ return;
+ }
+
value = util_conv_string (in_value, charset, "UTF-8");
if (value == NULL)
value = strdup (in_value);
@@ -438,27 +444,17 @@
{
free (ogg_info->artist);
ogg_info->artist = value;
- change = 1;
}
else if (strcmp (tag, "title") == 0)
{
free (ogg_info->title);
ogg_info->title = value;
- change = 1;
}
else if (strcmp (tag, "song") == 0)
{
- free (ogg_info->artist);
free (ogg_info->title);
- ogg_info->artist = NULL;
ogg_info->title = value;
- change = 1;
}
- if (change)
- {
- source_vorbis->stream_notify = 1;
- source_vorbis->rebuild_comment = 1;
- }
else
free (value);
}
More information about the commits
mailing list