[xiph-commits] r9210 - icecast/branches/kh/icecast/src

karl at motherfish-iii.xiph.org karl at motherfish-iii.xiph.org
Wed May 4 10:47:13 PDT 2005


Author: karl
Date: 2005-05-04 10:47:05 -0700 (Wed, 04 May 2005)
New Revision: 9210

Modified:
   icecast/branches/kh/icecast/src/cfgfile.c
   icecast/branches/kh/icecast/src/connection.c
   icecast/branches/kh/icecast/src/format.c
   icecast/branches/kh/icecast/src/format.h
   icecast/branches/kh/icecast/src/format_mp3.c
   icecast/branches/kh/icecast/src/format_ogg.c
   icecast/branches/kh/icecast/src/global.h
   icecast/branches/kh/icecast/src/logging.c
   icecast/branches/kh/icecast/src/slave.c
   icecast/branches/kh/icecast/src/source.c
   icecast/branches/kh/icecast/src/stats.c
   icecast/branches/kh/icecast/src/util.c
   icecast/branches/kh/icecast/src/util.h
   icecast/branches/kh/icecast/src/yp.c
Log:
check in work. shoutcast source clients refer to mount list before selecting
the password to use. reduce usage of time syscall. fixup explicit stream stats.
initial implementation of average rate estimation. Added new stats


Modified: icecast/branches/kh/icecast/src/cfgfile.c
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.c	2005-05-04 05:38:04 UTC (rev 9209)
+++ icecast/branches/kh/icecast/src/cfgfile.c	2005-05-04 17:47:05 UTC (rev 9210)
@@ -548,6 +548,7 @@
     mount->max_listeners = -1;
     mount->burst_size = -1;
     mount->mp3_meta_interval = -1;
+    mount->yp_public = -1;
     mount->next = NULL;
 
     do {

Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c	2005-05-04 05:38:04 UTC (rev 9209)
+++ icecast/branches/kh/icecast/src/connection.c	2005-05-04 17:47:05 UTC (rev 9210)
@@ -925,7 +925,11 @@
                     config = config_get_config();
                     if (config->listeners[i].shoutcast_compat) {
                         char *shoutcast_mount = strdup (config->shoutcast_mount);
-                        source_password = strdup(config->source_password);
+                        mount_proxy *mountinfo = config_find_mount (config, config->shoutcast_mount);
+                        if (mountinfo && mountinfo->password)
+                            source_password = strdup (mountinfo->password);
+                        else
+                            source_password = strdup (config->source_password);
                         config_release_config();
                         _handle_shoutcast_compatible(con, shoutcast_mount, source_password);
                         free(source_password);

Modified: icecast/branches/kh/icecast/src/format.c
===================================================================
--- icecast/branches/kh/icecast/src/format.c	2005-05-04 05:38:04 UTC (rev 9209)
+++ icecast/branches/kh/icecast/src/format.c	2005-05-04 17:47:05 UTC (rev 9210)
@@ -64,6 +64,17 @@
         return FORMAT_TYPE_GENERIC;
 }
 
+void format_free_plugin (format_plugin_t *format)
+{
+    if (format == NULL)
+        return;
+    rate_free (format->in_bitrate);
+    rate_free (format->out_bitrate);
+    if (format->free_plugin)
+        format->free_plugin (format);
+}
+
+
 int format_get_plugin (format_type_t type, source_t *source, http_parser_t *parser)
 {
     int ret = -1;
@@ -78,9 +89,8 @@
     default:
         break;
     }
-    if (ret < 0)
-        stats_event (source->mount, "content-type",
-                source->format->contenttype);
+    source->format->in_bitrate = rate_setup (10);
+    source->format->out_bitrate = rate_setup (10);
 
     return ret;
 }

Modified: icecast/branches/kh/icecast/src/format.h
===================================================================
--- icecast/branches/kh/icecast/src/format.h	2005-05-04 05:38:04 UTC (rev 9209)
+++ icecast/branches/kh/icecast/src/format.h	2005-05-04 17:47:05 UTC (rev 9210)
@@ -42,6 +42,8 @@
     char *contenttype;
     uint64_t read_bytes;
     uint64_t sent_bytes;
+    struct rate_calc *in_bitrate;
+    struct rate_calc *out_bitrate;
 
     refbuf_t *(*get_buffer)(struct source_tag *);
     int (*write_buf_to_client)(struct source_tag *source, client_t *client);
@@ -64,5 +66,7 @@
 int format_http_write_to_client (struct source_tag *source, client_t *client);
 int format_intro_write_to_client (struct source_tag *source, client_t *client);
 
+void format_free_plugin (format_plugin_t *format);
+
 #endif  /* __FORMAT_H__ */
 

Modified: icecast/branches/kh/icecast/src/format_mp3.c
===================================================================
--- icecast/branches/kh/icecast/src/format_mp3.c	2005-05-04 05:38:04 UTC (rev 9209)
+++ icecast/branches/kh/icecast/src/format_mp3.c	2005-05-04 17:47:05 UTC (rev 9210)
@@ -437,6 +437,7 @@
         return NULL;
     }
     format->read_bytes += bytes;
+    rate_add (format->in_bitrate, bytes, global.time);
     if (source_mp3->update_metadata)
     {
         mp3_set_title (source);
@@ -480,6 +481,7 @@
         return NULL;
     }
     format->read_bytes += ret;
+    rate_add (format->in_bitrate, ret, global.time);
     if (source_mp3->update_metadata)
     {
         mp3_set_title (source);

Modified: icecast/branches/kh/icecast/src/format_ogg.c
===================================================================
--- icecast/branches/kh/icecast/src/format_ogg.c	2005-05-04 05:38:04 UTC (rev 9209)
+++ icecast/branches/kh/icecast/src/format_ogg.c	2005-05-04 17:47:05 UTC (rev 9210)
@@ -426,6 +426,7 @@
             return NULL;
         }
         format->read_bytes += bytes;
+        rate_add (format->in_bitrate, bytes, global.time);
         ogg_sync_wrote (&ogg_info->oy, bytes);
     }
 }

Modified: icecast/branches/kh/icecast/src/global.h
===================================================================
--- icecast/branches/kh/icecast/src/global.h	2005-05-04 05:38:04 UTC (rev 9209)
+++ icecast/branches/kh/icecast/src/global.h	2005-05-04 17:47:05 UTC (rev 9210)
@@ -36,6 +36,8 @@
     int clients;
     int schedule_config_reread;
 
+    time_t time;
+
     avl_tree *source_tree;
     /* for locally defined relays */
     struct _relay_server *relays;

Modified: icecast/branches/kh/icecast/src/logging.c
===================================================================
--- icecast/branches/kh/icecast/src/logging.c	2005-05-04 05:38:04 UTC (rev 9209)
+++ icecast/branches/kh/icecast/src/logging.c	2005-05-04 17:47:05 UTC (rev 9210)
@@ -47,7 +47,7 @@
     char    sign;
     char    *timezone_string;
     struct tm gmt;
-    time_t time1 = time(NULL);
+    time_t time1 = global.time;
     int time_days, time_hours, time_tz;
     int tempnum1, tempnum2;
     struct tm *thetime;
@@ -84,7 +84,7 @@
     timezone_string = calloc(1, 7);
     snprintf(timezone_string, 7, " %c%.2d%.2d", sign, time_tz / 60, time_tz % 60);
 
-    now = time(NULL);
+    now = global.time;
 
     thetime = localtime(&now);
     strftime (buffer, len-7, "%d/%b/%Y:%H:%M:%S", thetime);
@@ -117,7 +117,7 @@
     time_t stayed;
     char *referrer, *user_agent;
 
-    now = time(NULL);
+    now = global.time;
 
     localtime_r (&now, &thetime);
     /* build the data */
@@ -170,7 +170,7 @@
         return;
     }
 
-    now = time(NULL);
+    now = global.time;
 
     localtime_r (&now, &thetime);
     /* build the data */

Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c	2005-05-04 05:38:04 UTC (rev 9209)
+++ icecast/branches/kh/icecast/src/slave.c	2005-05-04 17:47:05 UTC (rev 9210)
@@ -693,6 +693,7 @@
         thread_sleep (1000000);
         if (slave_running == 0)
             break;
+        time (&global.time);
         if (rescan_relays == 0 && max_interval > ++interval)
             continue;
 

Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c	2005-05-04 05:38:04 UTC (rev 9209)
+++ icecast/branches/kh/icecast/src/source.c	2005-05-04 17:47:05 UTC (rev 9210)
@@ -231,8 +231,7 @@
     source->new_listeners = 0;
     source->first_normal_client = NULL;
 
-    if (source->format && source->format->free_plugin)
-        source->format->free_plugin (source->format);
+    format_free_plugin (source->format);
     source->format = NULL;
 
     /* flush out the stream data, we don't want any left over */
@@ -256,7 +255,7 @@
     source->no_mount = 0;
     source->shoutcast_compat = 0;
     source->max_listeners = -1;
-    source->yp_public = 0;
+    source->yp_public = -1;
     source->yp_prevent = 0;
     source->hidden = 0;
     source->client_stats_update = 0;
@@ -465,7 +464,7 @@
     while (global.running == ICE_RUNNING && source->running)
     {
         int fds = 0;
-        time_t current = time(NULL);
+        time_t current = global.time;
         int delay = 200;
 
         /* service fast clients but jump out once in a while to check on
@@ -503,6 +502,10 @@
         }
         if (current >= source->client_stats_update)
         {
+            stats_event_args (source->mount, "outgoing_bitrate", "%ld", 
+                    8 * rate_avg (source->format->out_bitrate));
+            stats_event_args (source->mount, "incoming_bitrate", "%ld", 
+                    8 * rate_avg (source->format->in_bitrate));
             stats_event_args (source->mount, "total_bytes_read",
                     FORMAT_UINT64, source->format->read_bytes);
             stats_event_args (source->mount, "total_bytes_sent",
@@ -532,6 +535,7 @@
                 process_listeners (source, 1, 0);
                 continue;
             }
+            rate_add (source->format->in_bitrate, 0, global.time);
             break;
         }
         source->last_read = current;
@@ -626,6 +630,7 @@
 
         total_written += bytes;
     }
+    rate_add (source->format->out_bitrate, total_written, global.time);
     source->format->sent_bytes += total_written;
 
     /* the refbuf referenced at head (last in queue) may be marked for deletion
@@ -698,6 +703,8 @@
     {
         INFO2("listener count on %s now %d", source->mount, source->listeners);
         stats_event_args (source->mount, "listeners", "%d", source->listeners);
+        if (source->listeners == 0)
+            rate_add (source->format->out_bitrate, 0, 0);
         if (source->listeners == 0 && source->on_demand)
             source->running = 0;
     }
@@ -752,27 +759,32 @@
 
 static void source_init (source_t *source)
 {
-    char *str = NULL;
+    char *str = "0";
+    char buffer [100];
+    struct tm local;
 
     thread_mutex_lock (&source->lock);
-    do
+    if (source->yp_public < 0)
     {
-        str = "0";
-        if (source->yp_prevent)
-            break;
-        if ((str = httpp_getvar (source->client->parser, "ice-public")))
-            break;
-        if ((str = httpp_getvar (source->client->parser, "icy-pub")))
-            break;
-        if ((str = httpp_getvar (source->client->parser, "x-audiocast-public")))
-            break;
-        /* handle header from icecast v2 release */
-        if ((str = httpp_getvar (source->client->parser, "icy-public")))
-            break;
-        str = "0";
-    } while (0);
-    source->yp_public = atoi (str);
-    stats_event (source->mount, "public", str);
+
+        do
+        {
+            if (source->yp_prevent)
+                break;
+            if ((str = httpp_getvar (source->client->parser, "ice-public")))
+                break;
+            if ((str = httpp_getvar (source->client->parser, "icy-pub")))
+                break;
+            if ((str = httpp_getvar (source->client->parser, "x-audiocast-public")))
+                break;
+            /* handle header from icecast v2 release */
+            if ((str = httpp_getvar (source->client->parser, "icy-public")))
+                break;
+            str = "0";
+        } while (0);
+        source->yp_public = atoi (str);
+        stats_event (source->mount, "public", str);
+    }
     stats_event (source->mount, "server_type", source->format->contenttype);
 
     if (source->dumpfilename != NULL)
@@ -797,7 +809,7 @@
         sock_set_blocking (source->client->con->sock, SOCK_NONBLOCK);
 
     DEBUG0("Source creation complete");
-    source->last_read = time (NULL);
+    source->last_read = global.time;
     source->running = 1;
 
     source->audio_info = util_dict_new();
@@ -812,6 +824,10 @@
 
     thread_mutex_unlock (&source->lock);
 
+    localtime_r (&global.time, &local);
+    strftime (buffer, sizeof (buffer), "%a, %d %b %Y %H:%M:%S %z", &local);
+    stats_event (source->mount, "stream_start", buffer);
+
     if (source->on_connect)
         source_run_script (source->on_connect, source->mount);
 
@@ -1019,7 +1035,11 @@
     source->fallback_override = mountinfo->fallback_override;
     source->no_mount = mountinfo->no_mount;
     source->hidden = mountinfo->hidden;
+    source->yp_public = mountinfo->yp_public;
 
+    if (mountinfo->yp_public >= 0)
+        stats_event_args (source->mount, "public", "%d", mountinfo->yp_public);
+
     if (mountinfo->stream_name)
         stats_event (source->mount, "server_name", mountinfo->stream_name);
 
@@ -1041,9 +1061,6 @@
     if (mountinfo->subtype)
         stats_event (source->mount, "subtype", mountinfo->subtype);
 
-    if (mountinfo->yp_public)
-        source->yp_public = mountinfo->yp_public;
-
     if (mountinfo->auth)
         stats_event (source->mount, "authenticator", mountinfo->auth->type);
     else
@@ -1130,7 +1147,8 @@
             if (str) break;
             str = httpp_getvar(parser, "x-audiocast-name");
         } while (0);
-        stats_event (source->mount, "server_name", str);
+        if (str)
+            stats_event (source->mount, "server_name", str);
 
         do {
             str = httpp_getvar(parser, "ice-description");
@@ -1139,7 +1157,8 @@
             if (str) break;
             str = httpp_getvar(parser, "x-audiocast-description");
         } while (0);
-        stats_event (source->mount, "server_description", str);
+        if (str)
+            stats_event (source->mount, "server_description", str);
 
         do {
             str = httpp_getvar(parser, "ice-genre");
@@ -1148,7 +1167,8 @@
             if (str) break;
             str = httpp_getvar(parser, "x-audiocast-genre");
         } while (0);
-        stats_event (source->mount, "genre", str);
+        if (str)
+            stats_event (source->mount, "genre", str);
 
         do {
             str = httpp_getvar(parser, "ice-url");
@@ -1157,7 +1177,8 @@
             if (str) break;
             str = httpp_getvar(parser, "x-audiocast-url");
         } while (0);
-        stats_event (source->mount, "server_url", str);
+        if (str)
+            stats_event (source->mount, "server_url", str);
 
         do {
             str = httpp_getvar(parser, "ice-bitrate");
@@ -1166,7 +1187,8 @@
             if (str) break;
             str = httpp_getvar(parser, "x-audiocast-bitrate");
         } while (0);
-        stats_event (source->mount, "bitrate", str);
+        if (str)
+            stats_event (source->mount, "bitrate", str);
     }
 
     if (mountinfo)

Modified: icecast/branches/kh/icecast/src/stats.c
===================================================================
--- icecast/branches/kh/icecast/src/stats.c	2005-05-04 05:38:04 UTC (rev 9209)
+++ icecast/branches/kh/icecast/src/stats.c	2005-05-04 17:47:05 UTC (rev 9210)
@@ -538,8 +538,14 @@
     stats_event_t *event;
     stats_event_t *copy;
     event_listener_t *listener;
+    time_t now = time (NULL);
+    struct tm local;
+    char buffer[100];
 
     stats_event (NULL, "server", ICECAST_VERSION_STRING);
+    localtime_r (&now, &local);
+    strftime (buffer, sizeof (buffer), "%a, %d %b %Y %H:%M:%S %z", &local);
+    stats_event (NULL, "server_start", buffer);
 
     /* global currently active stats */
     stats_event (NULL, "clients", "0");

Modified: icecast/branches/kh/icecast/src/util.c
===================================================================
--- icecast/branches/kh/icecast/src/util.c	2005-05-04 05:38:04 UTC (rev 9209)
+++ icecast/branches/kh/icecast/src/util.c	2005-05-04 17:47:05 UTC (rev 9210)
@@ -49,6 +49,21 @@
 
 #include "logging.h"
 
+struct rate_calc_node
+{
+    time_t time;
+    long value;
+    struct rate_calc_node *next;
+};
+
+struct rate_calc
+{
+    unsigned int seconds;
+    unsigned int blocks;
+    struct rate_calc_node *current;
+};
+
+
 /* Abstract out an interface to use either poll or select depending on which
  * is available (poll is preferred) to watch a single fd.
  *
@@ -632,3 +647,89 @@
      return result;
 }
 #endif
+
+/* setup a rate block of so many seconds, so that an average can be
+ * determined of that range
+ */
+struct rate_calc *rate_setup (unsigned int seconds)
+{
+    struct rate_calc *calc = calloc (1, sizeof (struct rate_calc));
+    struct rate_calc_node *start;
+    int i;
+
+    if (calc == NULL || seconds == 0)
+    {
+        free (calc);
+        return NULL;
+    }
+    for (i=0 ; i <seconds; i++)
+    {
+        struct rate_calc_node *node = calloc (1, sizeof (*node));
+        if (calc->current)
+            calc->current->next = node;
+        else
+            start = node;
+        calc->current = node;
+    }
+    calc->current->next = start;
+    calc->seconds = seconds;
+    return calc;
+}
+
+
+/* add a value to sampled data, t is used to determine which sample
+ * block the sample goes into.
+ */
+void rate_add (struct rate_calc *calc, long value, time_t t)
+{
+    if (t == 0)
+    {
+        calc->blocks = 0;
+        return;
+    }
+    if (t != calc->current->time)
+    {
+        calc->current = calc->current->next;
+        calc->current->value = 0;
+        calc->current->time = t;
+        if (calc->blocks < calc->seconds)
+            calc->blocks++;
+    }
+    calc->current->value += value;
+}
+
+
+/* return the average sample value over all the blocks except the 
+ * current one, as that may be incomplete
+ */
+long rate_avg (struct rate_calc *calc)
+{
+    struct rate_calc_node *node = calc->current->next;
+    int i = calc->blocks;
+    long total = 0;
+
+    if (i < 2)
+        return 0;
+    i--;
+    for (; i; i--)
+    {
+        total += node->value;
+        node = node->next;
+    }
+    return total / (calc->blocks - 1);
+}
+
+
+void rate_free (struct rate_calc *calc)
+{
+    int i = calc->seconds;
+
+    for (; i; i--)
+    {
+        struct rate_calc_node *to_go = calc->current;
+        calc->current = to_go->next;
+        free (to_go);
+    }
+    free (calc);
+}
+

Modified: icecast/branches/kh/icecast/src/util.h
===================================================================
--- icecast/branches/kh/icecast/src/util.h	2005-05-04 05:38:04 UTC (rev 9209)
+++ icecast/branches/kh/icecast/src/util.h	2005-05-04 17:47:05 UTC (rev 9210)
@@ -52,4 +52,9 @@
 struct tm *localtime_r (const time_t *timep, struct tm *result);
 #endif
 
+struct rate_calc *rate_setup (unsigned int seconds);
+void rate_add (struct rate_calc *calc, long value, time_t t);
+long rate_avg (struct rate_calc *calc);
+void rate_free (struct rate_calc *calc);
+
 #endif  /* __UTIL_H__ */

Modified: icecast/branches/kh/icecast/src/yp.c
===================================================================
--- icecast/branches/kh/icecast/src/yp.c	2005-05-04 05:38:04 UTC (rev 9209)
+++ icecast/branches/kh/icecast/src/yp.c	2005-05-04 17:47:05 UTC (rev 9210)
@@ -354,7 +354,7 @@
     add_yp_info (yp, value, YP_BITRATE);
     free (value);
 
-    value = stats_get_value (yp->mount, "stream_description");
+    value = stats_get_value (yp->mount, "server_description");
     add_yp_info (yp, value, YP_SERVER_DESC);
     free (value);
 
@@ -373,7 +373,7 @@
     {
         yp->process = do_yp_touch;
         /* force first touch in 5 secs */
-        yp->next_update = time(NULL) + 5;
+        yp->next_update = global.time + 5;
     }
 
     return 0;
@@ -486,7 +486,7 @@
     yp = server->mounts;
     while (yp)
     {
-        now = time (NULL);
+        now = global.time;
         process_ypdata (server, yp);
         yp = yp->next;
     }



More information about the commits mailing list