[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