[xiph-cvs] cvs commit: vorbis-tools/ogg123 callbacks.c callbacks.h ogg123.c

Stan Seibert volsung at xiph.org
Thu Dec 13 08:20:19 PST 2001



volsung     01/12/13 08:20:19

  Modified:    ogg123   Tag: volsung_kc_20011011 callbacks.c callbacks.h
                        ogg123.c
  Log:
  Buffered status information works now.

Revision  Changes    Path
No                   revision

No                   revision

1.1.2.3   +156 -3    vorbis-tools/ogg123/Attic/callbacks.c

Index: callbacks.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogg123/Attic/callbacks.c,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- callbacks.c	2001/12/12 15:52:25	1.1.2.2
+++ callbacks.c	2001/12/13 16:20:17	1.1.2.3
@@ -11,7 +11,7 @@
  *                                                                  *
  ********************************************************************
 
- last mod: $Id: callbacks.c,v 1.1.2.2 2001/12/12 15:52:25 volsung Exp $
+ last mod: $Id: callbacks.c,v 1.1.2.3 2001/12/13 16:20:17 volsung Exp $
 
  ********************************************************************/
 
@@ -32,7 +32,7 @@
   return ret ? nbytes : 0;
 }
 
-void audio_reopen_callback (buf_t *buf, void *arg)
+void audio_reopen_action (buf_t *buf, void *arg)
 {
   audio_reopen_arg_t *reopen_arg = (audio_reopen_arg_t *) arg;
   audio_device_t *current;
@@ -139,7 +139,7 @@
 
 /* Statistics callbacks */
 
-void print_statistics_callback (buf_t *buf, void *arg)
+void print_statistics_action (buf_t *buf, void *arg)
 {
   print_statistics_arg_t *stats_arg = (print_statistics_arg_t *) arg;
   buffer_stats_t *buffer_stats;
@@ -177,4 +177,157 @@
   arg->decoder_statistics = decoder_statistics;
 
   return arg;
+}
+
+
+/* Decoder callbacks */
+
+void decoder_error_callback (void *arg, int severity, char *message, ...)
+{
+  va_list ap;
+
+  va_start(ap, message);
+  vstatus_error(message, ap);
+  va_end(ap);
+}
+
+
+void decoder_metadata_callback (void *arg, int verbosity, char *message, ...)
+{
+  va_list ap;
+
+  va_start(ap, message);
+  vstatus_message(verbosity, message, ap);
+  va_end(ap);
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+/* These actions are just wrappers for vstatus_message() and vstatus_error() */
+
+typedef struct status_message_arg_t {
+  int verbosity;
+  char *message;
+} status_message_arg_t;
+
+
+status_message_arg_t *new_status_message_arg (int verbosity)
+{
+  status_message_arg_t *arg;
+
+  if ( (arg = malloc(sizeof(status_message_arg_t))) == NULL ) {
+    status_error("Error: Out of memory in new_status_message_arg().\n");
+    exit(1);
+  }  
+  
+  arg->verbosity = verbosity;
+
+  return arg;
+}
+  
+
+void status_error_action (buf_t *buf, void *arg)
+{
+  status_message_arg_t *myarg = (status_message_arg_t *) arg;
+
+  status_error(myarg->message);
+
+  free(myarg->message);
+  free(myarg);
+}
+
+
+void status_message_action (buf_t *buf, void *arg)
+{
+  status_message_arg_t *myarg = (status_message_arg_t *) arg;
+
+  status_message(myarg->verbosity, myarg->message);
+
+  free(myarg->message);
+  free(myarg);
+}
+
+/* -------------------------------------------------------------- */
+
+void decoder_buffered_error_callback (void *arg, int severity, 
+				      char *message, ...)
+{
+  va_list ap;
+  buf_t *buf = (buf_t *)arg;
+  status_message_arg_t *sm_arg = new_status_message_arg(0);
+  int n, size = 80; /* Guess we need no more than 80 bytes. */
+
+
+  /* Preformat the string and allocate space for it.  This code taken
+     straight from the vsnprintf() man page.  We do this here because
+     we might need to reinit ap several times. */
+  if ((sm_arg->message = malloc (size)) == NULL) {
+    status_error("Error: Out of memory in decoder_buffered_metadata_callback().\n");
+    exit(1);
+  }
+  
+  while (1) {
+    /* Try to print in the allocated space. */
+    va_start(ap, message);
+    n = vsnprintf (sm_arg->message, size, message, ap);
+    va_end(ap);
+    
+    /* If that worked, return the string. */
+    if (n > -1 && n < size)
+      break;
+    /* Else try again with more space. */
+    if (n > -1)    /* glibc 2.1 */
+      size = n+1; /* precisely what is needed */
+    else           /* glibc 2.0 */
+      size *= 2;  /* twice the old size */
+    if ((sm_arg->message = realloc (sm_arg->message, size)) == NULL) {
+      status_error("Error: Out of memory in decoder_buffered_metadata_callback().\n");
+      exit(1);
+    }
+  }
+
+  /* Use vsnprintf! */
+  buffer_append_action_at_end(buf, &status_error_action, sm_arg);
+}
+
+
+void decoder_buffered_metadata_callback (void *arg, int verbosity, 
+					 char *message, ...)
+{
+  va_list ap;
+  buf_t *buf = (buf_t *)arg;
+  status_message_arg_t *sm_arg = new_status_message_arg(0);
+  int n, size = 80; /* Guess we need no more than 80 bytes. */
+
+
+  /* Preformat the string and allocate space for it.  This code taken
+     straight from the vsnprintf() man page.  We do this here because
+     we might need to reinit ap several times. */
+  if ((sm_arg->message = malloc (size)) == NULL) {
+    status_error("Error: Out of memory in decoder_buffered_metadata_callback().\n");
+    exit(1);
+  }
+  
+  while (1) {
+    /* Try to print in the allocated space. */
+    va_start(ap, message);
+    n = vsnprintf (sm_arg->message, size, message, ap);
+    va_end(ap);
+    
+    /* If that worked, return the string. */
+    if (n > -1 && n < size)
+      break;
+    /* Else try again with more space. */
+    if (n > -1)    /* glibc 2.1 */
+      size = n+1; /* precisely what is needed */
+    else           /* glibc 2.0 */
+      size *= 2;  /* twice the old size */
+    if ((sm_arg->message = realloc (sm_arg->message, size)) == NULL) {
+      status_error("Error: Out of memory in decoder_buffered_metadata_callback().\n");
+      exit(1);
+    }
+  }
+
+  buffer_append_action_at_end(buf, &status_message_action, sm_arg);
 }

1.1.2.2   +14 -3     vorbis-tools/ogg123/Attic/callbacks.h

Index: callbacks.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogg123/Attic/callbacks.h,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- callbacks.h	2001/12/11 18:46:22	1.1.2.1
+++ callbacks.h	2001/12/13 16:20:17	1.1.2.2
@@ -11,7 +11,7 @@
  *                                                                  *
  ********************************************************************
 
- last mod: $Id: callbacks.h,v 1.1.2.1 2001/12/11 18:46:22 volsung Exp $
+ last mod: $Id: callbacks.h,v 1.1.2.2 2001/12/13 16:20:17 volsung Exp $
 
  ********************************************************************/
 
@@ -38,7 +38,7 @@
 } audio_reopen_arg_t;
 
 int audio_play_callback (void *ptr, int nbytes, int eos, void *arg);
-void audio_reopen_callback (buf_t *buf, void *arg);
+void audio_reopen_action (buf_t *buf, void *arg);
 
 audio_reopen_arg_t *new_audio_reopen_arg (audio_device_t *devices,
                                           audio_format_t *fmt);
@@ -52,10 +52,21 @@
   decoder_stats_t *decoder_statistics;
 } print_statistics_arg_t;
 
-void print_statistics_callback (buf_t *buf, void *arg);
+void print_statistics_action (buf_t *buf, void *arg);
 print_statistics_arg_t *new_print_statistics_arg (
                                stat_format_t *stat_format,
                                data_source_stats_t *transport_statistics,
                                decoder_stats_t *decoder_statistics);
+
+
+/* Decoder callbacks */
+void decoder_error_callback (void *arg, int severity, char *message, ...);
+void decoder_metadata_callback (void *arg, int verbosity, char *message, ...);
+
+void decoder_buffered_error_callback (void *arg, int severity, 
+				      char *message, ...);
+void decoder_buffered_metadata_callback (void *arg, int verbosity, 
+					 char *message, ...);
+
 
 #endif /* __CALLBACKS_H__ */

1.39.2.30.2.19 +64 -56    vorbis-tools/ogg123/ogg123.c

Index: ogg123.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogg123/ogg123.c,v
retrieving revision 1.39.2.30.2.18
retrieving revision 1.39.2.30.2.19
diff -u -r1.39.2.30.2.18 -r1.39.2.30.2.19
--- ogg123.c	2001/12/12 15:52:25	1.39.2.30.2.18
+++ ogg123.c	2001/12/13 16:20:17	1.39.2.30.2.19
@@ -14,7 +14,7 @@
  *                                                                  *
  ********************************************************************
 
- last mod: $Id: ogg123.c,v 1.39.2.30.2.18 2001/12/12 15:52:25 volsung Exp $
+ last mod: $Id: ogg123.c,v 1.39.2.30.2.19 2001/12/13 16:20:17 volsung Exp $
 
  ********************************************************************/
 
@@ -179,6 +179,42 @@
   /* Put logic here to decide if this stream needs a total time display */
 }
 
+
+/* Handles printing statistics depending upon whether or not we have 
+   buffering going on */
+void display_statistics (stat_format_t *stat_format,
+			 buf_t *audio_buffer, 
+			 data_source_t *source,
+			 decoder_t *decoder)
+{
+  print_statistics_arg_t *pstats_arg;
+  buffer_stats_t *buffer_stats;
+
+  pstats_arg = new_print_statistics_arg(stat_format,
+					source->transport->statistics(source),
+					decoder->format->statistics(decoder));
+  if (audio_buffer) {
+    /* Place a status update into the buffer */
+    buffer_append_action_at_end(audio_buffer,
+				&print_statistics_action,
+				pstats_arg);
+    
+    /* And if we are not playing right now, do an immediate
+       update just the output buffer */
+    buffer_stats = buffer_statistics(audio_buffer);
+    if (buffer_stats->paused || buffer_stats->prebuffering) {
+      pstats_arg = new_print_statistics_arg(stat_format,
+					    NULL,
+					    NULL);
+      print_statistics_action(audio_buffer, pstats_arg);
+    }
+    free(buffer_stats);
+    
+  } else
+    print_statistics_action(NULL, pstats_arg);
+}
+
+
 void print_audio_devices_info(audio_device_t *d)
 {
   ao_info *info;
@@ -196,27 +232,6 @@
 }
 
 
-/* ----------------------------- callbacks ------------------------------ */
-
-void decoder_error_callback (void *arg, int severity, char *message, ...)
-{
-  va_list ap;
-
-  va_start(ap, message);
-  vstatus_error(message, ap);
-  va_end(ap);
-}
-
-void decoder_metadata_callback (void *arg, int verbosity, char *message, ...)
-{
-  va_list ap;
-
-  va_start(ap, message);
-  vstatus_message(verbosity, message, ap);
-  va_end(ap);
-}
-
-
 /* --------------------------- main code -------------------------------- */
 
 
@@ -302,26 +317,39 @@
   format_t *format;
   data_source_t *source;
   decoder_t *decoder;
-  decoder_callbacks_t decoder_callbacks = { &decoder_error_callback,
-					    &decoder_metadata_callback };
-  print_statistics_arg_t *pstats_arg;
-  buffer_stats_t *buffer_stats;
 
+  decoder_callbacks_t decoder_callbacks;
+  void *decoder_callbacks_arg;
+
   /* Preserve between calls so we only open the audio device when we 
      have to */
   static audio_format_t old_audio_fmt = { 0, 0, 0, 0, 0 };
   audio_format_t new_audio_fmt;
   audio_reopen_arg_t *reopen_arg;
 
+  /* Flags and counters galore */
   int eof = 0, eos = 0, ret;
   int nthc = 0, ntimesc = 0;
   int next_status = 0;
   int status_interval = 0;
 
+
+  /* Set preferred audio format (used by decoder) */
   new_audio_fmt.big_endian = ao_is_big_endian();
   new_audio_fmt.signed_sample = 1;
   new_audio_fmt.word_size = 2;
 
+  /* Select appropriate callbacks */
+  if (audio_buffer != NULL) {
+    decoder_callbacks.printf_error = &decoder_buffered_error_callback;
+    decoder_callbacks.printf_metadata = &decoder_buffered_error_callback;
+    decoder_callbacks_arg = audio_buffer;
+  } else {
+    decoder_callbacks.printf_error = &decoder_error_callback;
+    decoder_callbacks.printf_metadata = &decoder_error_callback;
+    decoder_callbacks_arg = NULL;
+  }
+
   /* Locate and use transport for this data source */  
   if ( (transport = select_transport(source_string)) == NULL ) {
     status_error("No module could be found to read from %s.\n", source_string);
@@ -340,7 +368,7 @@
   }
   
   if ( (decoder = format->init(source, &options, &new_audio_fmt, 
-			       &decoder_callbacks, NULL)) == NULL ) {
+			       &decoder_callbacks, audio_buffer)) == NULL ) {
     status_error("Error opening %s using the %s module."
                  "  The file may be corrupted.\n", source_string,
                  format->name);
@@ -416,42 +444,21 @@
         reopen_arg = new_audio_reopen_arg(options.devices, &new_audio_fmt);
 
         if (audio_buffer)	  
-	  buffer_insert_action_at_end(audio_buffer, &audio_reopen_callback,
+	  buffer_insert_action_at_end(audio_buffer, &audio_reopen_action,
                                       reopen_arg);
         else
-	  audio_reopen_callback(NULL, reopen_arg);
+	  audio_reopen_action(NULL, reopen_arg);
       }
       
 
       /* Update statistics display if needed */
       if (next_status <= 0) {
-	
-	pstats_arg = new_print_statistics_arg(stat_format,
-					      transport->statistics(source),
-					      format->statistics(decoder));
-	if (audio_buffer) {
-	  /* Place a status update into the buffer */
-	  buffer_append_action_at_end(audio_buffer,
-				      &print_statistics_callback,
-				      pstats_arg);
-
-	  /* And if we are not playing right now, do an immediate
-	     update just the output buffer */
-	  buffer_stats = buffer_statistics(audio_buffer);
-	  if (buffer_stats->paused || buffer_stats->prebuffering) {
-	    pstats_arg = new_print_statistics_arg(stat_format,
-						  NULL,
-						  NULL);
-	    print_statistics_callback(audio_buffer, pstats_arg);
-	  }
-
-	} else
-	  print_statistics_callback(NULL, pstats_arg);
-	
+	display_statistics(stat_format, audio_buffer, source, decoder); 
         next_status = status_interval;
       } else
         next_status -= ret;
 
+
       /* Write audio data block to output, skipping or repeating chunks
          as needed */
       do {
@@ -476,18 +483,19 @@
       buffer_mark_eos(audio_buffer);
   } /* End of logical bitstream loop */
   
+  /* Done playing this logical bitstream.  Clean up house. */
 
-  /* Done playing this logical bitstream.  Now we cleanup output buffer. */
+  /* Print final stats */
+  display_statistics(stat_format, audio_buffer, source, decoder); 
+
   if (audio_buffer) {
     
     if (!sig_request.exit && !sig_request.skipfile)
       buffer_wait_for_empty(audio_buffer);
-    
-    
+        
     buffer_thread_kill(audio_buffer);
   }
   
-
   alarm(0);  
   format->cleanup(decoder);
   transport->close(source);

--- >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