diff --git a/NEWS b/NEWS index 701760f20..0013fcb85 100644 --- a/NEWS +++ b/NEWS @@ -17,14 +17,19 @@ ver 0.21 (not yet released) ver 0.20.12 (not yet released) * input + - cdio_paranoia, ffmpeg, file, smbclient: reduce lock contention, + fixing lots of xrun problems - curl: fix seeking * decoder - ffmpeg: fix GCC 8 warning - vorbis: fix Tremor support * player - log message when decoder is too slow +* encoder + - vorbis: default to quality 3 * output - fix hanging playback with soxr resampler + - httpd: flush encoder after tag; fixes corrupt Vorbis stream ver 0.20.11 (2017/10/18) * storage diff --git a/doc/user.xml b/doc/user.xml index 4d4add06d..a739046bf 100644 --- a/doc/user.xml +++ b/doc/user.xml @@ -3068,8 +3068,8 @@ run</programlisting> </entry> <entry> Sets the quality for VBR. -1 is the lowest quality, - 10 is the highest quality. Cannot be used with - <varname>bitrate</varname>. + 10 is the highest quality. Defaults to 3. Cannot + be used with <varname>bitrate</varname>. </entry> </row> <row> diff --git a/src/encoder/plugins/VorbisEncoderPlugin.cxx b/src/encoder/plugins/VorbisEncoderPlugin.cxx index 68ea479ee..5a8e2826a 100644 --- a/src/encoder/plugins/VorbisEncoderPlugin.cxx +++ b/src/encoder/plugins/VorbisEncoderPlugin.cxx @@ -62,7 +62,7 @@ private: }; class PreparedVorbisEncoder final : public PreparedEncoder { - float quality; + float quality = 3; int bitrate; public: @@ -97,7 +97,7 @@ PreparedVorbisEncoder::PreparedVorbisEncoder(const ConfigBlock &block) value = block.GetBlockValue("bitrate"); if (value == nullptr) - throw std::runtime_error("neither bitrate nor quality defined"); + return; quality = -2.0; diff --git a/src/input/plugins/CdioParanoiaInputPlugin.cxx b/src/input/plugins/CdioParanoiaInputPlugin.cxx index e48d8f389..2b9bced5e 100644 --- a/src/input/plugins/CdioParanoiaInputPlugin.cxx +++ b/src/input/plugins/CdioParanoiaInputPlugin.cxx @@ -270,7 +270,10 @@ CdioParanoiaInputStream::Seek(offset_type new_offset) lsn_relofs = new_offset / CDIO_CD_FRAMESIZE_RAW; offset = new_offset; - cdio_paranoia_seek(para, lsn_from + lsn_relofs, SEEK_SET); + { + const ScopeUnlock unlock(mutex); + cdio_paranoia_seek(para, lsn_from + lsn_relofs, SEEK_SET); + } } size_t @@ -292,6 +295,8 @@ CdioParanoiaInputStream::Read(void *ptr, size_t length) //current sector was changed ? if (lsn_relofs != buffer_lsn) { + const ScopeUnlock unlock(mutex); + rbuf = cdio_paranoia_read(para, nullptr); s_err = cdda_errors(drv); diff --git a/src/input/plugins/FfmpegInputPlugin.cxx b/src/input/plugins/FfmpegInputPlugin.cxx index f2611c094..781567dac 100644 --- a/src/input/plugins/FfmpegInputPlugin.cxx +++ b/src/input/plugins/FfmpegInputPlugin.cxx @@ -104,7 +104,13 @@ input_ffmpeg_open(const char *uri, size_t FfmpegInputStream::Read(void *ptr, size_t read_size) { - auto result = avio_read(h, (unsigned char *)ptr, read_size); + int result; + + { + const ScopeUnlock unlock(mutex); + result = avio_read(h, (unsigned char *)ptr, read_size); + } + if (result <= 0) { if (result < 0) throw MakeFfmpegError(result, "avio_read() failed"); @@ -126,7 +132,12 @@ FfmpegInputStream::IsEOF() noexcept void FfmpegInputStream::Seek(offset_type new_offset) { - auto result = avio_seek(h, new_offset, SEEK_SET); + int64_t result; + + { + const ScopeUnlock unlock(mutex); + result = avio_seek(h, new_offset, SEEK_SET); + } if (result < 0) throw MakeFfmpegError(result, "avio_seek() failed"); diff --git a/src/input/plugins/FileInputPlugin.cxx b/src/input/plugins/FileInputPlugin.cxx index fc51715ad..2d2850c74 100644 --- a/src/input/plugins/FileInputPlugin.cxx +++ b/src/input/plugins/FileInputPlugin.cxx @@ -87,14 +87,24 @@ input_file_open(gcc_unused const char *filename, void FileInputStream::Seek(offset_type new_offset) { - reader.Seek((off_t)new_offset); + { + const ScopeUnlock unlock(mutex); + reader.Seek((off_t)new_offset); + } + offset = new_offset; } size_t FileInputStream::Read(void *ptr, size_t read_size) { - size_t nbytes = reader.Read(ptr, read_size); + size_t nbytes; + + { + const ScopeUnlock unlock(mutex); + nbytes = reader.Read(ptr, read_size); + } + offset += nbytes; return nbytes; } diff --git a/src/input/plugins/SmbclientInputPlugin.cxx b/src/input/plugins/SmbclientInputPlugin.cxx index 4b3026e40..b40eadb9a 100644 --- a/src/input/plugins/SmbclientInputPlugin.cxx +++ b/src/input/plugins/SmbclientInputPlugin.cxx @@ -125,9 +125,14 @@ input_smbclient_open(const char *uri, size_t SmbclientInputStream::Read(void *ptr, size_t read_size) { - smbclient_mutex.lock(); - ssize_t nbytes = smbc_read(fd, ptr, read_size); - smbclient_mutex.unlock(); + ssize_t nbytes; + + { + const ScopeUnlock unlock(mutex); + const std::lock_guard<Mutex> lock(smbclient_mutex); + nbytes = smbc_read(fd, ptr, read_size); + } + if (nbytes < 0) throw MakeErrno("smbc_read() failed"); @@ -138,9 +143,14 @@ SmbclientInputStream::Read(void *ptr, size_t read_size) void SmbclientInputStream::Seek(offset_type new_offset) { - smbclient_mutex.lock(); - off_t result = smbc_lseek(fd, new_offset, SEEK_SET); - smbclient_mutex.unlock(); + off_t result; + + { + const ScopeUnlock unlock(mutex); + const std::lock_guard<Mutex> lock(smbclient_mutex); + result = smbc_lseek(fd, new_offset, SEEK_SET); + } + if (result < 0) throw MakeErrno("smbc_lseek() failed"); diff --git a/src/output/plugins/httpd/HttpdOutputPlugin.cxx b/src/output/plugins/httpd/HttpdOutputPlugin.cxx index 731a5053a..89c306560 100644 --- a/src/output/plugins/httpd/HttpdOutputPlugin.cxx +++ b/src/output/plugins/httpd/HttpdOutputPlugin.cxx @@ -387,6 +387,7 @@ HttpdOutput::SendTag(const Tag &tag) try { encoder->SendTag(tag); + encoder->Flush(); } catch (const std::runtime_error &) { /* ignore */ }