From 0b72b870fb3c7cffb31a522f809c521cb15f89d8 Mon Sep 17 00:00:00 2001 From: thor Date: Sun, 26 Apr 2020 12:56:12 +0000 Subject: [PATCH] libout123: limit write block to 16K git-svn-id: svn://scm.orgis.org/mpg123/trunk@4655 35dc7657-300d-0410-a2e5-dc2837fedb53 --- NEWS | 2 ++ src/libout123/libout123.c | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index b372b697..91d9573c 100644 --- a/NEWS +++ b/NEWS @@ -84,6 +84,8 @@ -- Fixed out_play() abortion logic to better detect fatal situations (broken pipe). Needed on FreeBSD, while Linux buffers the issue away. Should resolve bug 283. +-- Limit size of buffer block being written in out123_play to 16K, avoiding + unnecessary failure with ALSA at least. -- Using SDL2 now if found. Output module code unchanged. -- Added hex and txt (plain text) printout. -- Eliminated a spots where error messages would still be printed diff --git a/src/libout123/libout123.c b/src/libout123/libout123.c index 99a34256..25b284a5 100644 --- a/src/libout123/libout123.c +++ b/src/libout123/libout123.c @@ -691,13 +691,19 @@ out123_play(out123_handle *ao, void *bytes, size_t count) else #endif { + // Write 16K in a piece as maximum, as I've seen random short + // writes of big blocks with ALSA. + int maxcount = 1<<14; + maxcount -= maxcount % ao->framesize; + if(maxcount < 1) + maxcount = ao->framesize; if(ao->flags & OUT123_MUTE) mute_block( bytes, count, ao->zerosample , MPG123_SAMPLESIZE(ao->format) ); do /* Playback in a loop to be able to continue after interruptions. */ { errno = 0; - int block = count > INT_MAX ? INT_MAX : count; + int block = count > maxcount ? maxcount : count; written = ao->write(ao, bytes, block); debug4( "written: %d errno: %i (%s), keep_on=%d" , written, errno, strerror(errno) @@ -707,7 +713,8 @@ out123_play(out123_handle *ao, void *bytes, size_t count) { ao->errcode = OUT123_DEV_PLAY; if(!AOQUIET) - error1("Error in writing audio (%s?)!", strerror(errno)); + merror( "Error in writing audio, wrote only %d of %d (%s?)!" + , written, block, strerror(errno) ); /* This is a serious issue ending this playback round. */ break; }