[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