Package: vorbis-tools Version: 1.2.0-1 Severity: normal Tags: patch
My test is: ./ogg123 -d wav -f - test.ogg | less then press q to quit less. Ogg123 will hang and start taking 100% of the CPU. The only way to stop it is "kill -9". I have 2 patches that fix the problem: Patch #1: stop-eating-my-cpu.patch: This fixes the main hanging/cpu spinning problem. Patch #2: dont-decode-after-pipe-closes.patch: This adds a return value to buffer_submit_data() so that ogg123 knows when the buffer has shut down due to an error. Without this it doesn't hang, but it continues to decode the input even though there's no place to write it to. I have attempted to submit these patches to the upstream mailing list. We'll see if they go through. -David -- System Information: Debian Release: lenny/sid APT prefers testing APT policy: (990, 'testing'), (500, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Kernel: Linux 2.6.24-1-686 (SMP w/2 CPU cores) Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) Shell: /bin/sh linked to /bin/bash Versions of packages vorbis-tools depends on: ii libao2 0.8.8-4 Cross Platform Audio Output Librar ii libc6 2.7-10 GNU C Library: Shared libraries ii libcurl3-gnutls 7.18.0-1+b1 Multi-protocol file transfer libra ii libflac8 1.2.1-1.2 Free Lossless Audio Codec - runtim ii libkrb53 1.6.dfsg.3~beta1-4 MIT Kerberos runtime libraries ii libogg0 1.1.3-3 Ogg Bitstream Library ii libspeex1 1.1.12-3 The Speex Speech Codec ii libvorbis0a 1.2.0.dfsg-3 The Vorbis General Audio Compressi ii libvorbisenc2 1.2.0.dfsg-3 The Vorbis General Audio Compressi ii libvorbisfile3 1.2.0.dfsg-3 The Vorbis General Audio Compressi vorbis-tools recommends no packages. -- no debconf information
Index: ogg123/buffer.c =================================================================== --- ogg123.orig/buffer.c 2008-05-01 19:21:12.000000000 -0700 +++ ogg123/buffer.c 2008-05-01 19:32:16.000000000 -0700 @@ -207,7 +207,7 @@ /* This test is safe since curfill will never decrease and eos will never be unset. */ - while ( !(buf->eos && buf->curfill == 0)) { + while ( !(buf->eos && buf->curfill == 0) && !buf->abort_write) { if (buf->cancel_flag || sig_request.cancel) break; @@ -251,6 +251,11 @@ write_amount == buf->curfill ? buf->eos : 0, buf->write_arg); + if (!write_amount) { + DEBUG("Error writing to the audio device. Aborting."); + buffer_abort_write(buf); + } + LOCK_MUTEX(buf->mutex); buf->curfill -= write_amount; @@ -746,7 +751,7 @@ pthread_cleanup_push(buffer_mutex_unlock, buf); LOCK_MUTEX(buf->mutex); - while (!empty) { + while (!empty && !buf->abort_write) { if (buf->curfill > 0) { DEBUG1("Buffer curfill = %ld, going back to sleep.", buf->curfill);
Index: ogg123/buffer.c =================================================================== --- ogg123.orig/buffer.c 2008-05-01 19:32:16.000000000 -0700 +++ ogg123/buffer.c 2008-05-01 19:32:34.000000000 -0700 @@ -283,7 +283,7 @@ } -void submit_data_chunk (buf_t *buf, char *data, size_t size) +int submit_data_chunk (buf_t *buf, char *data, size_t size) { long buf_write_pos; /* offset of first available write location */ size_t write_size; @@ -346,6 +346,7 @@ pthread_cleanup_pop(0); DEBUG("Exit submit_data_chunk"); + return !buf->abort_write; } @@ -520,8 +521,8 @@ /* --- Data buffering functions --- */ -void buffer_submit_data (buf_t *buf, char *data, long nbytes) { - submit_data_chunk (buf, data, nbytes); +int buffer_submit_data (buf_t *buf, char *data, long nbytes) { + return submit_data_chunk (buf, data, nbytes); } size_t buffer_get_data (buf_t *buf, char *data, long nbytes) Index: ogg123/buffer.h =================================================================== --- ogg123.orig/buffer.h 2008-05-01 19:30:59.000000000 -0700 +++ ogg123/buffer.h 2008-05-01 19:32:34.000000000 -0700 @@ -110,7 +110,7 @@ void buffer_thread_kill (buf_t *buf); /* --- Data buffering functions --- */ -void buffer_submit_data (buf_t *buf, char *data, long nbytes); +int buffer_submit_data (buf_t *buf, char *data, long nbytes); size_t buffer_get_data (buf_t *buf, char *data, long nbytes); void buffer_mark_eos (buf_t *buf); Index: ogg123/http_transport.c =================================================================== --- ogg123.orig/http_transport.c 2008-05-01 19:30:59.000000000 -0700 +++ ogg123/http_transport.c 2008-05-01 19:32:34.000000000 -0700 @@ -68,7 +68,8 @@ if (myarg->cancel_flag || sig_request.cancel) return 0; - buffer_submit_data(myarg->buf, ptr, size*nmemb); + if (!buffer_submit_data(myarg->buf, ptr, size*nmemb)) + return 0; if (myarg->cancel_flag || sig_request.cancel) return 0; Index: ogg123/ogg123.c =================================================================== --- ogg123.orig/ogg123.c 2008-05-01 19:30:59.000000000 -0700 +++ ogg123/ogg123.c 2008-05-01 19:35:12.000000000 -0700 @@ -702,9 +702,13 @@ do { if (nthc-- == 0) { - if (audio_buffer) - buffer_submit_data(audio_buffer, convbuffer, ret); - else + if (audio_buffer) { + if (!buffer_submit_data(audio_buffer, convbuffer, ret)) { + status_error(_("Error: buffer write failed.\n")); + eof = eos = 1; + break; + } + } else audio_play_callback(convbuffer, ret, eos, &audio_play_arg); nthc = options.nth - 1;