[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