[xiph-cvs] cvs commit: ices/src input.c
Karl Heyes
karl at xiph.org
Wed Jul 9 16:44:11 PDT 2003
karl 03/07/09 19:44:11
Modified: src input.c
Log:
replace ogg page based timing function, as the previous wasn't working
correctly with ogg files which have a non-zero starting timecode.
Revision Changes Path
1.29 +75 -45 ices/src/input.c
Index: input.c
===================================================================
RCS file: /usr/local/cvsroot/ices/src/input.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- input.c 28 Mar 2003 01:07:37 -0000 1.28
+++ input.c 9 Jul 2003 23:44:11 -0000 1.29
@@ -2,7 +2,7 @@
* - Main producer control loop. Fetches data from input modules, and controls
* submission of these to the instance threads. Timing control happens here.
*
- * $Id: input.c,v 1.28 2003/03/28 01:07:37 karl Exp $
+ * $Id: input.c,v 1.29 2003/07/09 23:44:11 karl Exp $
*
* Copyright (c) 2001 Michael Smith <msmith at labyrinth.net.au>
*
@@ -89,7 +89,7 @@
{NULL,NULL}
};
-static timing_control _control, *control = &_control;
+static timing_control control;
/* This is identical to shout_sync(), really. */
@@ -98,10 +98,10 @@
int64_t sleep;
/* no need to sleep if we haven't sent data */
- if (control->senttime == 0) return;
+ if (control.senttime == 0) return;
- sleep = ((double)control->senttime / 1000) -
- (timing_get_time() - control->starttime);
+ sleep = ((double)control.senttime / 1000) -
+ (timing_get_time() - control.starttime);
/* trap for long sleeps, typically indicating a clock change. it's not */
/* perfect though, as low bitrate/low samplerate vorbis can trigger this */
@@ -116,63 +116,93 @@
int input_calculate_pcm_sleep(unsigned bytes, unsigned bytes_per_sec)
{
- control->senttime += ((uint64_t)bytes * 1000000)/bytes_per_sec;
+ control.senttime += ((uint64_t)bytes * 1000000)/bytes_per_sec;
return 0;
}
int input_calculate_ogg_sleep(ogg_page *page)
{
- /* Largely copied from shout_send(), without the sending happening.*/
- ogg_stream_state os;
+ static ogg_stream_state os;
ogg_packet op;
- vorbis_info vi;
- vorbis_comment vc;
- int ret = 0;
+ static vorbis_info vi;
+ static vorbis_comment vc;
+ static int need_start_pos, need_headers, state_in_use = 0;
+ static uint64_t offset;
+ static uint64_t first_granulepos;
+ if (ogg_page_granulepos(page) == -1)
+ {
+ LOG_ERROR0("Timing control: corrupt timing information in vorbis file, cannot stream.");
+ return -1;
+ }
if (ogg_page_bos (page))
{
- control->serialno = ogg_page_serialno(page);
-
- control->oldsamples = 0;
-
- ogg_stream_init(&os, control->serialno);
- ogg_stream_pagein(&os, page);
- ogg_stream_packetout(&os, &op);
+ control.oldsamples = 0;
- vorbis_info_init(&vi);
- vorbis_comment_init(&vc);
+ if (state_in_use)
+ ogg_stream_clear (&os);
+ ogg_stream_init (&os, ogg_page_serialno (page));
+ state_in_use = 1;
+ vorbis_info_init (&vi);
+ vorbis_comment_init (&vc);
+ need_start_pos = 1;
+ need_headers = 3;
+ offset = (uint64_t)0;
+ }
+ if (need_start_pos)
+ {
+ int found_first_granulepos = 0;
- if(vorbis_synthesis_headerin(&vi, &vc, &op) < 0)
+ ogg_stream_pagein (&os, page);
+ while (ogg_stream_packetout (&os, &op) == 1)
{
- LOG_ERROR0("Timing control: can't determine sample rate for input, "
- "not vorbis.");
- control->samplerate = 0;
- ret = -1;
+ if (need_headers)
+ {
+ if (vorbis_synthesis_headerin (&vi, &vc, &op) < 0)
+ {
+ LOG_ERROR0("Timing control: can't determine sample rate for input, not vorbis.");
+ control.samplerate = 0;
+ return -1;
+ }
+ need_headers--;
+ control.samplerate = vi.rate;
+
+ if (need_headers == 0)
+ {
+ vorbis_comment_clear (&vc);
+ first_granulepos = (uint64_t)0;
+ return 0;
+ }
+ continue;
+ }
+ /* headers have been read */
+ if (first_granulepos == 0 && op.granulepos > 0)
+ {
+ first_granulepos = op.granulepos;
+ found_first_granulepos = 1;
+ }
+ offset += vorbis_packet_blocksize (&vi, &op) / 4;
}
- else
- control->samplerate = vi.rate;
+ if (!found_first_granulepos)
+ return 0;
- vorbis_comment_clear(&vc);
- vorbis_info_clear(&vi);
- ogg_stream_clear(&os);
+ need_start_pos = 0;
+ control.oldsamples = first_granulepos - offset;
+ vorbis_info_clear (&vi);
+ ogg_stream_clear (&os);
+ state_in_use = 0;
}
+ control.samples = ogg_page_granulepos (page) - control.oldsamples;
+ control.oldsamples = ogg_page_granulepos (page);
- if(ogg_page_granulepos(page) == -1)
- {
- LOG_ERROR0("Timing control: corrupt timing information in vorbis file, cannot stream.");
- return -1;
- }
+ control.senttime += ((uint64_t)control.samples * 1000000 /
+ (uint64_t)control.samplerate);
- control->samples = ogg_page_granulepos(page) - control->oldsamples;
- control->oldsamples = ogg_page_granulepos(page);
+ return 0;
+}
- if(control->samplerate)
- control->senttime += ((double)control->samples * 1000000 /
- (double)control->samplerate);
- return ret;
-}
void input_flush_queue(buffer_queue *queue, int keep_critical)
{
@@ -249,7 +279,7 @@
thread_mutex_create(&ices_config->refcount_lock);
thread_mutex_create(&ices_config->flush_lock);
- memset (control, 0, sizeof (*control));
+ memset (&control, 0, sizeof (control));
while(ices_config->playlist_module && modules[current_module].open)
{
@@ -359,8 +389,8 @@
* be done before the call to inmod->getdata() below, in order to
* properly keep time if this input module blocks.
*/
- if(control->starttime == 0)
- control->starttime = timing_get_time();
+ if (control.starttime == 0)
+ control.starttime = timing_get_time();
/* get a chunk of data from the input module */
ret = inmod->getdata(inmod->internal, chunk);
<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