Commit f80fe10d authored by ivo's avatar ivo

Apply two patches from David Caldwell:

* fix CPU issue when outputting to a closed pipe
* return value to stop decoding after buffer is shut down
Closes #1357

svn path=/trunk/vorbis-tools/; revision=14957
parent 958a8193
......@@ -3,6 +3,8 @@ vorbis-tools 1.2.1 -- Unreleased
* Fixed an error in configure.ac; --with-speex/flac work again (#1319)
* Corrected problems in the Visual Studio project files
* ogg123: backported fix from libfishsound to patch the Speex decoder (#1347)
* ogg123: fixed CPU issue when outputting to a closed pipe (#1357)
* ogg123: return value to stop decoding after buffer is shut down (#1357)
* oggenc: fixed a core dump while resampling from FLAC (#1316)
* oggenc: fixed a typo in the Skeleton handling routine
* ogginfo: support for information in Kate streams (#1360)
......
......@@ -207,7 +207,7 @@ void *buffer_thread_func (void *arg)
/* 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 @@ void *buffer_thread_func (void *arg)
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;
......@@ -278,7 +283,7 @@ void *buffer_thread_func (void *arg)
}
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;
......@@ -341,6 +346,7 @@ void submit_data_chunk (buf_t *buf, char *data, size_t size)
pthread_cleanup_pop(0);
DEBUG("Exit submit_data_chunk");
return !buf->abort_write;
}
......@@ -515,8 +521,8 @@ void buffer_thread_kill (buf_t *buf)
/* --- 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)
......@@ -746,7 +752,7 @@ void buffer_wait_for_empty (buf_t *buf)
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);
......
......@@ -110,7 +110,7 @@ void buffer_thread_unpause (buf_t *buf);
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);
......
......@@ -68,7 +68,8 @@ size_t write_callback (void *ptr, size_t size, size_t nmemb, void *arg)
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;
......
......@@ -239,10 +239,10 @@ int handle_seek_opt(ogg123_options_t *options, decoder_t *decoder, format_t *for
}
options->seekmode = DECODER_SEEK_NONE;
return 1;
}
/* This function selects which statistics to display for our
particular configuration. This does not have anything to do with
verbosity, but rather with which stats make sense to display. */
......@@ -271,7 +271,7 @@ void select_stats (stat_format_t *stats, ogg123_options_t *opts,
stats[7].enabled = 0;
}
free(data_source_stats);
/* Assume we need total time display, and let display_statistics()
determine at what point it should be turned off during playback */
stats[2].enabled = 1; /* Remaining playback time */
......@@ -294,14 +294,14 @@ void display_statistics (stat_format_t *stat_format,
decoder->format->statistics(decoder));
if (options.remote) {
/* Display statistics via the remote interface */
remote_time(pstats_arg->decoder_statistics->current_time,
pstats_arg->decoder_statistics->total_time,
pstats_arg->decoder_statistics->instant_bitrate);
} else {
/* Disable/Enable statistics as needed */
if (pstats_arg->decoder_statistics->total_time <
......@@ -447,8 +447,8 @@ int main(int argc, char **argv)
print_audio_devices_info(options.devices);
/* Setup buffer */
/* Setup buffer */
if (options.buffer_size > 0) {
/* Keep sample size alignment for surround sound with up to 10 channels */
options.buffer_size = (options.buffer_size + PRIMAGIC - 1) / PRIMAGIC * PRIMAGIC;
......@@ -473,7 +473,6 @@ int main(int argc, char **argv)
signal (SIGTERM, signal_handler);
if (options.remote) {
/* run the mainloop for the remote interface */
remote_mainloop();
......@@ -483,9 +482,9 @@ int main(int argc, char **argv)
/* Shuffle playlist */
if (options.shuffle) {
int i;
srandom(time(NULL));
for (i = 0; i < items; i++) {
int j = i + random() % (items - i);
char *temp = playlist_array[i];
......@@ -568,7 +567,7 @@ void play (char *source_string)
status_error(_("The file format of %s is not supported.\n"), source_string);
return;
}
if ( (decoder = format->init(source, &options, &new_audio_fmt,
&decoder_callbacks,
decoder_callbacks_arg)) == NULL ) {
......@@ -586,7 +585,7 @@ void play (char *source_string)
/* Start the audio playback thread before we begin sending data */
if (audio_buffer != NULL) {
/* First reset mutexes and other synchronization variables */
buffer_reset (audio_buffer);
buffer_thread_start (audio_buffer);
......@@ -614,11 +613,11 @@ void play (char *source_string)
/* Main loop: Iterates over all of the logical bitstreams in the file */
while (!eof && !sig_request.exit) {
/* Loop through data within a logical bitstream */
eos = 0;
while (!eos && !sig_request.exit) {
/* Check signals */
if (sig_request.skipfile) {
eof = eos = 1;
......@@ -664,7 +663,6 @@ void play (char *source_string)
break;
}
/* Check to see if the audio format has changed */
if (!audio_format_equal(&new_audio_fmt, &old_audio_fmt)) {
old_audio_fmt = new_audio_fmt;
......@@ -682,7 +680,7 @@ void play (char *source_string)
else
audio_reopen_action(NULL, reopen_arg);
}
/* Update statistics display if needed */
if (next_status <= 0) {
......@@ -702,11 +700,15 @@ void play (char *source_string)
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;
}
......@@ -714,15 +716,15 @@ void play (char *source_string)
++ntimesc < options.ntimes);
ntimesc = 0;
} /* End of data loop */
} /* End of logical bitstream loop */
/* Done playing this logical bitstream. Clean up house. */
if (audio_buffer) {
if (!sig_request.exit && !sig_request.skipfile) {
buffer_mark_eos(audio_buffer);
buffer_wait_for_empty(audio_buffer);
......@@ -733,14 +735,13 @@ void play (char *source_string)
/* Print final stats */
display_statistics_quick(stat_format, audio_buffer, source, decoder);
format->cleanup(decoder);
transport->close(source);
status_reset_output_lock(); /* In case we were killed mid-output */
status_message(1, _("Done."));
if (sig_request.exit)
exit (exit_status);
}
......@@ -748,7 +749,7 @@ void play (char *source_string)
void exit_cleanup ()
{
if (audio_buffer != NULL) {
buffer_destroy (audio_buffer);
audio_buffer = NULL;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment