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

karl at dactyl.lonelymoon.com karl
Mon Jul 19 14:28:15 PDT 2004


Author: karl
Date: Mon Jul 19 14:28:15 2004
New Revision: 7176

Modified:
icecast/branches/kh/icecast/src/format_mp3.c
icecast/branches/kh/icecast/src/format_ogg.c
icecast/branches/kh/icecast/src/format_vorbis.c
icecast/branches/kh/icecast/src/refbuf.c
icecast/branches/kh/icecast/src/refbuf.h
icecast/branches/kh/icecast/src/source.c
Log:
various updates, some cleanups, fixup some mp3 metadata via url problems
make re-sync to trunk easier


Modified: icecast/branches/kh/icecast/src/format_mp3.c
===================================================================
--- icecast/branches/kh/icecast/src/format_mp3.c	2004-07-19 16:01:03 UTC (rev 7175)
+++ icecast/branches/kh/icecast/src/format_mp3.c	2004-07-19 21:28:12 UTC (rev 7176)
@@ -95,7 +95,6 @@

meta = refbuf_new (1);
memcpy (meta->data, "", 1);
-    meta->len = 1;
state->metadata = meta;
state->interval = ICY_METADATA_INTERVAL;

@@ -135,18 +134,17 @@
source_mp3->url_title = p;
source_mp3->update_metadata = 1;
}
-        return;
}
-    if (strcmp (tag, "artist") == 0)
+    else if (strcmp (tag, "artist") == 0)
{
char *p = strdup (value);
if (p)
{
free (source_mp3->url_artist);
source_mp3->url_artist = p;
+            source_mp3->update_metadata = 1;
}
}
-    source_mp3->update_metadata = 1;
}


@@ -178,15 +176,19 @@
}


-void mp3_set_title (source_t *source)
+/* called from the source thread when the metadata has been updated.
+ * The artist title are checked and made ready for clients to send
+ */
+static void mp3_set_title (source_t *source)
{
const char meta[] = "StreamTitle='";
int size;
unsigned char len_byte;
refbuf_t *p;
-    unsigned len = sizeof(meta) + 6;
+    unsigned len = sizeof(meta) + 2; /* the StreamTitle, quotes, ; and null */
mp3_state *source_mp3 = source->format->_state;

+    /* work out message length */
if (source_mp3->url_artist)
len += strlen (source_mp3->url_artist);
if (source_mp3->url_title)
@@ -194,16 +196,18 @@
if (source_mp3->url_artist && source_mp3->url_title)
len += 3;
#define MAX_META_LEN 255*16
-    size  = sizeof (meta) + len + 2;
-    if (len > MAX_META_LEN-(sizeof(meta)+3))
+    if (len > MAX_META_LEN)
{
WARN1 ("Metadata too long at %d chars", len);
return;
}
-    len_byte = size / 16 + 1;
+    /* work out the metadata len byte */
+    len_byte = (len-1) / 16 + 1;
+
+    /* now we know how much space to allocate, +1 for the len byte */
size = len_byte * 16 + 1;
+
p = refbuf_new (size);
-    p->len = size;
if (p)
{
mp3_state *source_mp3 = source->format->_state;
@@ -213,13 +217,20 @@
snprintf (p->data, size, "%c%s%s - %s';", len_byte, meta,
source_mp3->url_artist, source_mp3->url_title);
else
-            snprintf (p->data, size, "%c%s%.*s';", len_byte, meta, len, source_mp3->url_title);
+            snprintf (p->data, size, "%c%s%s';", len_byte, meta,
+                    source_mp3->url_title);
filter_shoutcast_metadata (source, p->data, size);
+
+        refbuf_release (source_mp3->metadata);
source_mp3->metadata = p;
}
}


+/* send the appropriate metadata, and return the number of bytes written
+ * 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)
{
int ret = 0;
@@ -227,6 +238,9 @@
int meta_len;
mp3_client_data *client_mp3 = client->format_data;

+    /* If there is a change in metadata then send it else
+     * send a single zero value byte in its place
+     */
if (associated == client_mp3->associated)
{
metadata = "\0";
@@ -249,14 +263,17 @@
}
if (ret > 0)
client_mp3->metadata_offset += ret;
+    else
+        ret = 0;
client_mp3->in_metadata = 1;

return ret;
}


-/* return bytes actually written, -1 for error or 0 for no more data to write */
-
+/* Handler for writing mp3 data to a client, taking into account whether
+ * client has requested shoutcast style metadata updates
+ */
static int format_mp3_write_buf_to_client (format_plugin_t *self, client_t *client)
{
int ret, written = 0;
@@ -281,14 +298,15 @@
refbuf_t *associated = refbuf->associated;
ret = send_mp3_metadata (client, associated);

-            if (ret < (int)associated->len)
+            if (client_mp3->in_metadata)
break;
written += ret;
}
/* see if we need to send the current metadata to the client */
if (client_mp3->use_metadata)
{
-            unsigned remaining = source_mp3->interval - client_mp3->since_meta_block;
+            unsigned remaining = source_mp3->interval -
+                client_mp3->since_meta_block;

/* sending the metadata block */
if (remaining <= len)
@@ -331,7 +349,7 @@
written += ret;
}
ret = 0;
-        /* we have now written what we need to in here */
+        /* we have now written what we needed to so move to the next buffer */
if (refbuf->next)
{
client->refbuf = refbuf->next;
@@ -341,28 +359,32 @@

if (ret > 0)
written += ret;
-    return written ? written : -1;
+    return written;
}

static void format_mp3_free_plugin (format_plugin_t *plugin)
{
/* free the plugin instance */
-    mp3_state *state = plugin->_state;
+    mp3_state *format_mp3 = plugin->_state;

-    free(state);
+    free (format_mp3->url_artist);
+    free (format_mp3->url_title);
+    refbuf_release (format_mp3->metadata);
+    free(format_mp3);
free(plugin);
}


+/* read an mp3 stream which does not have shoutcast style metadata */
static refbuf_t *mp3_get_no_meta (source_t *source)
{
int bytes;
refbuf_t *refbuf;
mp3_state *source_mp3 = source->format->_state;

-    if ((refbuf = refbuf_new (4096)) == NULL)
+    if ((refbuf = refbuf_new (2048)) == NULL)
return NULL;
-    bytes = sock_read_bytes (source->con->sock, refbuf->data, 4096);
+    bytes = sock_read_bytes (source->con->sock, refbuf->data, 2048);

if (bytes == 0)
{
@@ -380,6 +402,7 @@
{
refbuf->len  = bytes;
refbuf->associated = source_mp3->metadata;
+        refbuf_addref (source_mp3->metadata);
refbuf->sync_point = 1;
return refbuf;
}
@@ -392,6 +415,10 @@
}


+/* read mp3 data with inlined metadata from the source. Filter out the
+ * metadata so that the mp3 data itself is store on the queue and the
+ * metadata is is associated with it
+ */
static refbuf_t *mp3_get_filter_meta (source_t *source)
{
refbuf_t *refbuf;
@@ -428,10 +455,11 @@
return NULL;
}
/* fill the buffer with the read data */
-    bytes = (unsigned)ret;
+    bytes = (unsigned int)ret;
+    refbuf->len = 0;
while (bytes > 0)
{
-        unsigned metadata_remaining;
+        unsigned int metadata_remaining;

mp3_block = source_mp3->inline_metadata_interval - source_mp3->offset;

@@ -442,7 +470,8 @@
source_mp3->offset += bytes;
break;
}
-        /* we have enough data to get to the metadata block, but only transfer upto it */
+        /* we have enough data to get to the metadata
+         * block, but only transfer upto it */
if (mp3_block)
{
src += mp3_block;
@@ -452,25 +481,29 @@
continue;
}

-        /* are we processing the inline metadata, len == 0 indicates not seen any */
+        /* process the inline metadata, len == 0 indicates not seen any yet */
if (source_mp3->build_metadata_len == 0)
{
-            memset (source_mp3->build_metadata, 0, sizeof (source_mp3->build_metadata));
+            memset (source_mp3->build_metadata, 0,
+                    sizeof (source_mp3->build_metadata));
source_mp3->build_metadata_offset = 0;
source_mp3->build_metadata_len = 1 + (*src * 16);
}

/* do we have all of the metatdata block */
-        metadata_remaining = source_mp3->build_metadata_len - source_mp3->build_metadata_offset;
+        metadata_remaining = source_mp3->build_metadata_len -
+            source_mp3->build_metadata_offset;
if (bytes < metadata_remaining)
{
-            memcpy (source_mp3->build_metadata + source_mp3->build_metadata_offset,
-                    src, bytes);
+            memcpy (source_mp3->build_metadata +
+                    source_mp3->build_metadata_offset, src, bytes);
source_mp3->build_metadata_offset += bytes;
break;
}
+        /* copy all bytes except the last one, that way we *
+         * know a null byte terminates the message */
memcpy (source_mp3->build_metadata + source_mp3->build_metadata_offset,
-                src, metadata_remaining);
+                src, metadata_remaining-1);

/* overwrite metadata in the buffer */
bytes -= metadata_remaining;
@@ -480,13 +513,15 @@
if (source_mp3->build_metadata_len > 1)
{
refbuf_t *meta = refbuf_new (source_mp3->build_metadata_len);
-            memcpy (meta->data, source_mp3->build_metadata, source_mp3->build_metadata_len);
-            meta->len = source_mp3->build_metadata_len;
+            memcpy (meta->data, source_mp3->build_metadata,
+                    source_mp3->build_metadata_len);

DEBUG1("shoutcast metadata %.4080s", meta->data+1);
if (strncmp (meta->data+1, "StreamTitle=", 12) == 0)
{
-                filter_shoutcast_metadata (source, source_mp3->build_metadata, source_mp3->build_metadata_len);
+                filter_shoutcast_metadata (source, source_mp3->build_metadata,
+                        source_mp3->build_metadata_len);
+                refbuf_release (source_mp3->metadata);
source_mp3->metadata = meta;
}
else
@@ -501,6 +536,7 @@
source_mp3->build_metadata_len = 0;
}
refbuf->associated = source_mp3->metadata;
+    refbuf_addref (source_mp3->metadata);
refbuf->sync_point = 1;

return refbuf;

Modified: icecast/branches/kh/icecast/src/format_ogg.c
===================================================================
--- icecast/branches/kh/icecast/src/format_ogg.c	2004-07-19 16:01:03 UTC (rev 7175)
+++ icecast/branches/kh/icecast/src/format_ogg.c	2004-07-19 21:28:12 UTC (rev 7176)
@@ -105,10 +105,8 @@
{
refbuf_t *refbuf = refbuf_new (page->header_len + page->body_len);

-    refbuf->idx = ogg_page_pageno (page);
memcpy (refbuf->data, page->header, page->header_len);
memcpy (refbuf->data+page->header_len, page->body, page->body_len);
-    refbuf->len = page->header_len + page->body_len;
return refbuf;
}

@@ -365,7 +363,6 @@
return NULL;
}
refbuf = make_refbuf_with_page (page);
-    refbuf->idx = ogg_page_pageno (page);

// DEBUG2 ("granulepos is %lld,  %p", granulepos, refbuf);
if (granulepos == -1 || granulepos == theora->prev_granulepos)
@@ -446,9 +443,22 @@
static void free_ogg_codecs (ogg_state_t *ogg_info)
{
ogg_codec_t *codec;
+    refbuf_t *header;

if (ogg_info == NULL)
return;
+    /* release the header pages first */
+    header = ogg_info->header_pages;
+    while (header)
+    {
+        refbuf_t *to_release = header;
+        header = header->next;
+        refbuf_release (to_release);
+    }
+    ogg_info->header_pages = NULL;
+    ogg_info->header_pages_tail = NULL;
+
+    /* now free the codecs */
codec = ogg_info->codecs;
while (codec)
{
@@ -515,8 +525,6 @@
ogg_info->codec_sync = NULL;
/* need to zap old list of codecs when next group of BOS pages appear */
free_ogg_codecs (ogg_info);
-        ogg_info->header_pages = NULL;
-        ogg_info->header_pages_tail = NULL;
}
do
{
@@ -567,7 +575,15 @@
{
refbuf_t *refbuf = codec->process_page (codec, page);
if (refbuf)
+            {
+                refbuf_t *header = ogg_info->header_pages;
+                while (header)
+                {
+                    refbuf_addref (header);
+                    header = header->next;
+                }
refbuf->associated = ogg_info->header_pages;
+            }
return refbuf;
}
codec = codec->next;
@@ -758,7 +774,7 @@

if (ret > 0)
written += ret;
-    return written ? written : -1;
+    return written;
}



Modified: icecast/branches/kh/icecast/src/format_vorbis.c
===================================================================
--- icecast/branches/kh/icecast/src/format_vorbis.c	2004-07-19 16:01:03 UTC (rev 7175)
+++ icecast/branches/kh/icecast/src/format_vorbis.c	2004-07-19 21:28:12 UTC (rev 7176)
@@ -226,6 +226,7 @@
}
if (get_ogg_page (&source_vorbis->out_os, &page) > 0)
{
+        refbuf *header;
/* printf ("got audio page %lld\n", ogg_page_granulepos (&page)); */
/* squeeze a page copy into a buffer */
source_vorbis->samples_in_page -= (ogg_page_granulepos (&page) - source_vorbis->prev_page_samples);
@@ -234,8 +235,13 @@
refbuf = refbuf_new (page.header_len + page.body_len);
memcpy (refbuf->data, page.header, page.header_len);
memcpy (refbuf->data+page.header_len, page.body, page.body_len);
-        refbuf->len = page.header_len + page.body_len;
refbuf->associated = source_vorbis->headers_head;
+        header = source_vorbis->headers_head;
+        while (header)
+        {
+            refbuf_addref (header);
+            header = header->next;
+        }
/* printf ("setting associated to %p\n", refbuf->associated); */
}
return refbuf;
@@ -299,7 +305,6 @@
source_vorbis->headers_head = NULL;
source_vorbis->headers_tail = NULL;
source_vorbis->get_buffer_page = get_buffer_header;
-    /* printf ("stream cleared\n"); */
return NULL;
}


Modified: icecast/branches/kh/icecast/src/refbuf.c
===================================================================
--- icecast/branches/kh/icecast/src/refbuf.c	2004-07-19 16:01:03 UTC (rev 7175)
+++ icecast/branches/kh/icecast/src/refbuf.c	2004-07-19 21:28:12 UTC (rev 7176)
@@ -33,48 +33,50 @@
{
}

-
-void refbuf_free (refbuf_t *refbuf)
-{
-    free (refbuf->data);
-    free (refbuf);
-}
-
-
refbuf_t *refbuf_new(unsigned long size)
{
refbuf_t *refbuf;

-    refbuf = malloc (sizeof(refbuf_t));
-    if (refbuf)
+    refbuf = (refbuf_t *)malloc(sizeof(refbuf_t));
+    if (refbuf == NULL)
+        return NULL;
+    refbuf->data = NULL;
+    if (size)
{
-        refbuf->data = NULL;
-        if (size && (refbuf->data = malloc (size)) == NULL)
+        refbuf->data = malloc (size);
+        if (refbuf->data == NULL)
{
free (refbuf);
return NULL;
}
-        refbuf->len = 0;
-        refbuf->sync_point = 0;
-        refbuf->allocated = size;
-        refbuf->next = NULL;
-        refbuf->associated = NULL;
-        refbuf->refbuf_associated_release = refbuf_free;
-        refbuf->refbuf_release = refbuf_free;
}
+    refbuf->len = size;
+    refbuf->sync_point = 0;
+    refbuf->_count = 1;
+    refbuf->next = NULL;
+    refbuf->associated = NULL;

return refbuf;
}

+void refbuf_addref(refbuf_t *self)
+{
+    self->_count++;
+}

-void refbuf_release(refbuf_t *refbuf)
+void refbuf_release(refbuf_t *self)
{
-    while (refbuf->associated)
-    {
-        refbuf_t *ref = refbuf->associated;
-        refbuf->associated = ref->next;
-        refbuf->refbuf_associated_release (ref);
+    self->_count--;
+    if (self->_count == 0) {
+        while (self->associated)
+        {
+            refbuf_t *ref = self->associated;
+            self->associated = ref->next;
+            refbuf_release (ref);
+        }
+        if (self->len)
+            free(self->data);
+        free(self);
}
-    refbuf->refbuf_release (refbuf);
}


Modified: icecast/branches/kh/icecast/src/refbuf.h
===================================================================
--- icecast/branches/kh/icecast/src/refbuf.h	2004-07-19 16:01:03 UTC (rev 7175)
+++ icecast/branches/kh/icecast/src/refbuf.h	2004-07-19 21:28:12 UTC (rev 7176)
@@ -21,31 +21,20 @@
typedef struct _refbuf_tag
{
char *data;
-    unsigned len;
-    unsigned allocated;
-    int idx;
+    unsigned int len;
int sync_point;
struct _refbuf_tag *associated;
-    void (*refbuf_associated_release)(struct _refbuf_tag *);
-    void (*refbuf_release)(struct _refbuf_tag *);
-
struct _refbuf_tag *next;
+    unsigned long _count;
} refbuf_t;

void refbuf_initialize(void);
void refbuf_shutdown(void);

-void refbuf_free (refbuf_t *refbuf);
refbuf_t *refbuf_new(unsigned long size);
+void refbuf_addref(refbuf_t *self);
void refbuf_release(refbuf_t *self);


#endif  /* __REFBUF_H__ */

-
-
-
-
-
-
-

Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c	2004-07-19 16:01:03 UTC (rev 7175)
+++ icecast/branches/kh/icecast/src/source.c	2004-07-19 21:28:12 UTC (rev 7176)
@@ -234,8 +234,6 @@
{
refbuf_t *p = source->stream_data;
source->stream_data = p->next;
-        if (source->stream_data && p->associated == source->stream_data->associated)
-            p->associated = NULL;
refbuf_release (p);
}
source->stream_data_tail = NULL;
@@ -1019,12 +1017,10 @@
if (remove_from_q)
{
refbuf_t *to_go = source->stream_data;
-            /* associated data is shared so don't release it if the next refbuf refers to it */
+
if (to_go->next)
{
source->stream_data = to_go->next;
-                if (to_go->associated == source->stream_data->associated)
-                    to_go->associated = NULL;
source->queue_size -= to_go->len;
if (source->burst_point == to_go)
{



More information about the commits mailing list