[xiph-cvs] cvs commit: ices/src im_playlist.c im_stdinpcm.c input.c input.h

Karl Heyes karl at xiph.org
Thu Mar 6 20:20:55 PST 2003



karl        03/03/06 23:20:55

  Modified:    src      im_playlist.c im_stdinpcm.c input.c input.h
  Log:
  push sleep decisions for the input thread down to the specific input
  module. Not doing this can cause some audio corruption when reading from
  live input.  Other inputs are unaffected by this.

Revision  Changes    Path
1.7       +8 -1      ices/src/im_playlist.c

Index: im_playlist.c
===================================================================
RCS file: /usr/local/cvsroot/ices/src/im_playlist.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- im_playlist.c	3 Aug 2002 15:05:38 -0000	1.6
+++ im_playlist.c	7 Mar 2003 04:20:55 -0000	1.7
@@ -1,7 +1,7 @@
 /* playlist.c
  * - Basic playlist functionality
  *
- * $Id: im_playlist.c,v 1.6 2002/08/03 15:05:38 msmith Exp $
+ * $Id: im_playlist.c,v 1.7 2003/03/07 04:20:55 karl Exp $
  *
  * Copyright (c) 2001 Michael Smith <msmith at labyrinth.net.au>
  *
@@ -24,6 +24,7 @@
 #include "event.h"
 
 #include "inputmodule.h"
+#include "input.h"
 #include "im_playlist.h"
 
 #include "playlist_basic.h"
@@ -153,6 +154,11 @@
                         LOG_WARN1("Corrupt or missing data in file (%s)", pl->filename);
                 else if(result > 0)
                 {
+            if (input_calculate_ogg_sleep (&og) < 0)
+            {
+                pl->nexttrack = 1;
+                return 0;
+            }
                         rb->len = og.header_len + og.body_len;
                         rb->buf = malloc(rb->len);
                         rb->aux_data = og.header_len;
@@ -189,6 +195,7 @@
         }
 
         pl->errors=0;
+    input_sleep ();
 
         return rb->len;
 }

<p><p>1.4       +4 -2      ices/src/im_stdinpcm.c

Index: im_stdinpcm.c
===================================================================
RCS file: /usr/local/cvsroot/ices/src/im_stdinpcm.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- im_stdinpcm.c	3 Aug 2002 15:05:38 -0000	1.3
+++ im_stdinpcm.c	7 Mar 2003 04:20:55 -0000	1.4
@@ -1,7 +1,7 @@
 /* im_stdinpcm.c
  * - Raw PCM input from stdin
  *
- * $Id: im_stdinpcm.c,v 1.3 2002/08/03 15:05:38 msmith Exp $
+ * $Id: im_stdinpcm.c,v 1.4 2003/03/07 04:20:55 karl Exp $
  *
  * Copyright (c) 2001 Michael Smith <msmith at labyrinth.net.au>
  *
@@ -23,7 +23,7 @@
 #include "stream.h"
 
 #include "inputmodule.h"
-
+#include "input.h"
 #include "im_stdinpcm.h"
 
 #define MODULE "input-stdinpcm/"
@@ -86,6 +86,8 @@
                 free(rb->buf);
                 return -1;
         }
+    input_calculate_pcm_sleep (rb->len, rb->aux_data);
+    input_sleep ();
 
         return rb->len;
 }

<p><p>1.23      +24 -34    ices/src/input.c

Index: input.c
===================================================================
RCS file: /usr/local/cvsroot/ices/src/input.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- input.c	2 Mar 2003 21:16:27 -0000	1.22
+++ input.c	7 Mar 2003 04:20:55 -0000	1.23
@@ -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.22 2003/03/02 21:16:27 karl Exp $
+ * $Id: input.c,v 1.23 2003/03/07 04:20:55 karl Exp $
  * 
  * Copyright (c) 2001 Michael Smith <msmith at labyrinth.net.au>
  *
@@ -58,9 +58,9 @@
 {
         uint64_t starttime;
         uint64_t senttime;
-	int samples;
-	int oldsamples;
-	int samplerate;
+	uint64_t samples;
+	uint64_t oldsamples;
+	unsigned samplerate;
         long serialno;
 } timing_control;
 
@@ -85,8 +85,11 @@
         {NULL,NULL}
 };
 
+static timing_control _control, *control = &_control;
+
+
 /* This is identical to shout_sync(), really. */
-static void _sleep(timing_control *control)
+void input_sleep(void)
 {
         int64_t sleep;
 
@@ -96,7 +99,9 @@
         sleep = ((double)control->senttime / 1000) - 
                 (timing_get_time() - control->starttime);
 
-    if(sleep > 5000) {
+    /* trap for long sleeps, typically indicating a clock change.  it's not */
+    /* perfect though, as low bitrate/low samplerate vorbis can trigger this */
+    if(sleep > 8000) {
         LOG_WARN1("Extended sleep requested (%ld ms), sleeping for 5 seconds",
                 sleep);
         timing_sleep(5000);
@@ -105,35 +110,30 @@
         timing_sleep((uint64_t)sleep);
 }
 
-static int _calculate_pcm_sleep(ref_buffer *buf, timing_control *control)
+int input_calculate_pcm_sleep(unsigned bytes, unsigned bytes_per_sec)
 {
-	control->senttime += ((double)buf->len * 1000000.)/((double)buf->aux_data);
+	control->senttime += ((uint64_t)bytes * 1000000)/bytes_per_sec;
 
     return 0;
 }
 
-static int _calculate_ogg_sleep(ref_buffer *buf, timing_control *control)
+int input_calculate_ogg_sleep(ogg_page *page)
 {
         /* Largely copied from shout_send(), without the sending happening.*/
         ogg_stream_state os;
-	ogg_page og;
         ogg_packet op;
         vorbis_info vi;
         vorbis_comment vc;
     int ret = 0;
 
-	og.header_len = buf->aux_data;
-	og.body_len = buf->len - buf->aux_data;
-	og.header = buf->buf;
-	og.body = buf->buf + og.header_len;
-
-	if(control->serialno != ogg_page_serialno(&og)) {
-		control->serialno = ogg_page_serialno(&og);
+	if (ogg_page_bos (page))
+    {
+		control->serialno = ogg_page_serialno(page);
 
                 control->oldsamples = 0;
 
                 ogg_stream_init(&os, control->serialno);
-		ogg_stream_pagein(&os, &og);
+		ogg_stream_pagein(&os, page);
                 ogg_stream_packetout(&os, &op);
 
                 vorbis_info_init(&vi);
@@ -154,13 +154,14 @@
                 ogg_stream_clear(&os);
         }
 
-    if(ogg_page_granulepos(&og) == -1) {
+    if(ogg_page_granulepos(page) == -1)
+    {
         LOG_ERROR0("Timing control: corrupt timing information in vorbis file, cannot stream.");
         return -1;
     }
 
-	control->samples = ogg_page_granulepos(&og) - control->oldsamples;
-	control->oldsamples = ogg_page_granulepos(&og);
+	control->samples = ogg_page_granulepos(page) - control->oldsamples;
+	control->oldsamples = ogg_page_granulepos(page);
 
     if(control->samplerate) 
             control->senttime += ((double)control->samples * 1000000 / 
@@ -231,7 +232,6 @@
 void input_loop(void)
 {
         input_module_t *inmod=NULL;
-	timing_control *control = calloc(1, sizeof(timing_control));
         instance_t *instance, *prev, *next;
         queue_item *queued;
         int shutdown = 0;
@@ -245,6 +245,8 @@
         thread_mutex_create(&ices_config->refcount_lock);
         thread_mutex_create(&ices_config->flush_lock);
 
+    memset (control, 0, sizeof (*control));
+
         while(ices_config->playlist_module && modules[current_module].open)
         {
                 if(!strcmp(ices_config->playlist_module, modules[current_module].name))
@@ -379,17 +381,6 @@
         if(chunk->critical)
             valid_stream = 1;
 
-		/* figure out how much time the data represents */
-		switch(inmod->type)
-		{
-			case ICES_INPUT_VORBIS:
-				ret = _calculate_ogg_sleep(chunk, control);
-				break;
-			case ICES_INPUT_PCM:
-				ret = _calculate_pcm_sleep(chunk, control);
-				break;
-		}
-
         if(ret < 0) {
             /* Tell the input module to go to the next track, hopefully allowing
              * resync. */
@@ -481,7 +472,6 @@
                     /* wake up the instances */
                     thread_cond_broadcast(&ices_config->queue_cond);
 
-		    _sleep(control);
         }
         }
 

<p><p>1.7       +5 -1      ices/src/input.h

Index: input.h
===================================================================
RCS file: /usr/local/cvsroot/ices/src/input.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- input.h	3 Aug 2002 08:14:54 -0000	1.6
+++ input.h	7 Mar 2003 04:20:55 -0000	1.7
@@ -1,7 +1,7 @@
 /* input.h
  * - Input functions
  *
- * $Id: input.h,v 1.6 2002/08/03 08:14:54 msmith Exp $
+ * $Id: input.h,v 1.7 2003/03/07 04:20:55 karl Exp $
  *
  * Copyright (c) 2001 Michael Smith <msmith at labyrinth.net.au>
  *
@@ -38,6 +38,10 @@
 
 void input_loop(void);
 void input_flush_queue(buffer_queue *queue, int keep_critical);
+void input_sleep(void);
+int  input_calculate_ogg_sleep(ogg_page *og);
+int  input_calculate_pcm_sleep(unsigned bytes, unsigned bytes_per_sec);
+
 
 #endif /* __INPUT_H__ */
 

<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