[xiph-cvs] cvs commit: libshout/src vorbis.c
Michael Smith
msmith at xiph.org
Wed Apr 2 04:09:04 PST 2003
msmith 03/04/02 07:09:04
Modified: src vorbis.c
Log:
Make vorbis handler in libshout not trust ogg page granulepos values, calculate
them directly. Neccesary for accurate timing control where there may be
granulepos gaps (as in a libshout client that optionally takes input from an
icecast stream).
This needs to be rolled into ices2 at some point, too.
Revision Changes Path
1.6 +56 -21 libshout/src/vorbis.c
Index: vorbis.c
===================================================================
RCS file: /usr/local/cvsroot/libshout/src/vorbis.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- vorbis.c 9 Mar 2003 22:56:46 -0000 1.5
+++ vorbis.c 2 Apr 2003 12:09:04 -0000 1.6
@@ -17,12 +17,17 @@
typedef struct {
/* total pages broadcasted */
unsigned int pages;
- /* the number of samples for the current page */
- unsigned int samples;
- unsigned int oldsamples;
unsigned int samplerate;
+
ogg_sync_state oy;
+ ogg_stream_state os;
+
+ int headers;
+ vorbis_info vi;
+ vorbis_comment vc;
+ int prevW;
+
long serialno;
} vorbis_data_t;
@@ -46,16 +51,29 @@
return SHOUTERR_SUCCESS;
}
+static int blocksize(vorbis_data_t *vd, ogg_packet *p)
+{
+ int this = vorbis_packet_blocksize(&vd->vi, p);
+ int ret = (this + vd->prevW)/4;
+
+ if(!vd->prevW)
+ {
+ vd->prevW = this;
+ return 0;
+ }
+
+ vd->prevW = this;
+ return ret;
+}
+
static int send_vorbis(shout_t *self, const unsigned char *data, size_t len)
{
vorbis_data_t *vorbis_data = (vorbis_data_t *)self->format_data;
int ret;
char *buffer;
- ogg_stream_state os;
ogg_page og;
ogg_packet op;
- vorbis_info vi;
- vorbis_comment vc;
+ int samples;
buffer = ogg_sync_buffer(&vorbis_data->oy, len);
memcpy(buffer, data, len);
@@ -63,29 +81,46 @@
while (ogg_sync_pageout(&vorbis_data->oy, &og) == 1) {
if (vorbis_data->serialno != ogg_page_serialno(&og)) {
- vorbis_data->serialno = ogg_page_serialno(&og);
- vorbis_data->oldsamples = 0;
+ /* Clear the old one - this is safe even if there was no previous
+ * stream */
+ vorbis_comment_clear(&vorbis_data->vc);
+ vorbis_info_clear(&vorbis_data->vi);
+ ogg_stream_clear(&vorbis_data->os);
- ogg_stream_init(&os, vorbis_data->serialno);
- ogg_stream_pagein(&os, &og);
- ogg_stream_packetout(&os, &op);
+ vorbis_data->serialno = ogg_page_serialno(&og);
- vorbis_info_init(&vi);
- vorbis_comment_init(&vc);
- vorbis_synthesis_headerin(&vi, &vc, &op);
+ ogg_stream_init(&vorbis_data->os, vorbis_data->serialno);
- vorbis_data->samplerate = vi.rate;
+ vorbis_info_init(&vorbis_data->vi);
+ vorbis_comment_init(&vorbis_data->vc);
- vorbis_comment_clear(&vc);
- vorbis_info_clear(&vi);
- ogg_stream_clear(&os);
+ vorbis_data->headers = 1;
}
- vorbis_data->samples = ogg_page_granulepos(&og) - vorbis_data->oldsamples;
- vorbis_data->oldsamples = ogg_page_granulepos(&og);
+ samples = 0;
+
+ ogg_stream_pagein(&vorbis_data->os, &og);
+ while(ogg_stream_packetout(&vorbis_data->os, &op) == 1) {
+ int size;
+
+ if(vorbis_data->headers > 0 && vorbis_data->headers <= 3) {
+ vorbis_synthesis_headerin(&vorbis_data->vi, &vorbis_data->vc,
+ &op);
+ if(vorbis_data->headers == 1)
+ vorbis_data->samplerate = vorbis_data->vi.rate;
+
+ vorbis_data->headers++;
+ continue;
+ }
+
+ vorbis_data->headers = 0;
+ size = blocksize(vorbis_data, &op);
+ samples += size;
+ }
- self->senttime += ((double)vorbis_data->samples * 1000000 / (double)vorbis_data->samplerate);
+ self->senttime += ((double)samples * 1000000) /
+ ((double)vorbis_data->samplerate);
ret = sock_write_bytes(self->socket, og.header, og.header_len);
if (ret != og.header_len)
<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