[xiph-cvs] cvs commit: icecast/src format_mp3.c format_mp3.h

Michael Smith msmith at xiph.org
Mon Dec 30 03:22:59 PST 2002



msmith      02/12/30 06:22:59

  Modified:    src      format_mp3.c format_mp3.h
  Log:
  More mp3 metadata work.
  Untested but more or less complete.
  No way to actually set the metadata yet.

Revision  Changes    Path
1.5       +85 -6     icecast/src/format_mp3.c

Index: format_mp3.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/format_mp3.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- format_mp3.c	30 Dec 2002 07:55:56 -0000	1.4
+++ format_mp3.c	30 Dec 2002 11:22:59 -0000	1.5
@@ -37,14 +37,17 @@
         source_t *source, client_t *client);
 
 typedef struct {
+   int use_metadata;
    int interval;
    int offset;
-   int metadata;
+   int metadata_age;
+   int metadata_offset;
 } mp3_client_data;
 
 format_plugin_t *format_mp3_get_plugin(void)
 {
         format_plugin_t *plugin;
+    mp3_state *state = calloc(1, sizeof(mp3_state));
 
         plugin = (format_plugin_t *)malloc(sizeof(format_plugin_t));
 
@@ -58,18 +61,91 @@
         plugin->free_plugin = format_mp3_free_plugin;
     plugin->format_description = "MP3 audio";
 
-	plugin->_state = calloc(1, sizeof(mp3_state));
+	plugin->_state = state;
+
+    thread_mutex_create(&(state->lock));
 
         return plugin;
 }
 
-static int format_mp3_write_buf_to_client(format_plugin_t *self, 
-    client_t *client, unsigned char *buf, int len) 
+/* TODO: need locking around source_state->metadata!! */
+
+static int send_metadata(client_t *client, mp3_client_data *client_state,
+        mp3_state *source_state)
 {
+    int send_metadata;
+    int len_byte;
+    int len;
+    unsigned char *buf;
     int ret;
+    int source_age;
+
+    thread_mutex_lock(&(source_state->lock));
+    if(source_state->metadata == NULL) {
+        /* Shouldn't be possible */
+        thread_mutex_unlock(&(source_state->lock));
+        return 0;
+    }
+
+    source_age = source_state->metadata_age;
+    send_metadata = (source_age != client_state->metadata_age) || 
+        client_state->metadata_offset;
+    len_byte = send_metadata?(strlen(source_state->metadata)/16 + 1 - 
+            client_state->metadata_offset):0;
+    len = 1 + len_byte*16;
+    buf = alloca(len);
+
+    memset(buf, 0, len);
+
+    buf[0] = len_byte;
+
+    strncpy(buf+1, source_state->metadata + client_state->metadata_offset, 
+            len-2);
+
+    thread_mutex_unlock(&(source_state->lock));
 
     ret = sock_write_bytes(client->con->sock, buf, len);
 
+    if(ret > 0 && ret < len) {
+        client_state->metadata_offset += ret;
+    }
+    else if(ret == len) {
+        client_state->metadata_age = source_age;
+        client_state->offset = 0;
+        client_state->metadata_offset = 0;
+    }
+
+    return ret;
+}
+
+static int format_mp3_write_buf_to_client(format_plugin_t *self, 
+    client_t *client, unsigned char *buf, int len) 
+{
+    int ret;
+    
+    if(((mp3_state *)self->_state)->metadata) 
+    {
+        mp3_client_data *state = client->format_data;
+        int max = state->interval - state->offset;
+
+        if(len == 0) /* Shouldn't happen */
+            return 0;
+
+        if(max > len)
+            max = len;
+
+        if(max > 0) {
+            ret = sock_write_bytes(client->con->sock, buf, max);
+            if(ret > 0)
+                state->offset += ret;
+        }
+        else
+            ret = send_metadata(client, state, self->_state);
+    }
+    else {
+        ret = sock_write_bytes(client->con->sock, buf, len);
+    }
+
     if(ret < 0) {
         if(sock_recoverable(ret)) {
             DEBUG1("Client had recoverable error %ld", ret);
@@ -85,6 +161,9 @@
 static void format_mp3_free_plugin(format_plugin_t *self)
 {
         /* free the plugin instance */
+    mp3_state *state = self->_state;
+    thread_mutex_destroy(&(state->lock));
+    free(state);
         free(self);
 }
 
@@ -120,7 +199,7 @@
 
     metadata = httpp_getvar(source->parser, "icy-metadata");
     if(metadata)
-    data->metadata = atoi(metadata)>0?1:0;
+        data->use_metadata = atoi(metadata)>0?1:0;
 
     return data;
 }
@@ -140,7 +219,7 @@
 
     format_send_general_headers(self, source, client);
 
-    if(0 && ((mp3_client_data *)(client->format_data))->metadata) {
+    if(((mp3_client_data *)(client->format_data))->use_metadata) {
         int bytes = sock_write(client->con->sock, "icy-metaint: %d\r\n", 
                 ICY_METADATA_INTERVAL);
         if(bytes > 0)

<p><p>1.3       +1 -0      icecast/src/format_mp3.h

Index: format_mp3.h
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/format_mp3.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- format_mp3.h	30 Dec 2002 07:55:56 -0000	1.2
+++ format_mp3.h	30 Dec 2002 11:22:59 -0000	1.3
@@ -9,6 +9,7 @@
 typedef struct {
     char *metadata;
     int metadata_age;
+    mutex_t lock;
 } mp3_state;
 
 format_plugin_t *format_mp3_get_plugin(void);

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list