From c266fb77581030e28aaad77298e4b9be6462f456 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 12 Jul 2022 10:47:52 +0200 Subject: [PATCH] encoder/lame: Read() returns the internal buffer Eliminate memcpy() calls. --- src/encoder/plugins/LameEncoderPlugin.cxx | 26 ++++--------- src/encoder/plugins/TwolameEncoderPlugin.cxx | 39 +++++++------------- 2 files changed, 21 insertions(+), 44 deletions(-) diff --git a/src/encoder/plugins/LameEncoderPlugin.cxx b/src/encoder/plugins/LameEncoderPlugin.cxx index 1e90ce89e..597e51536 100644 --- a/src/encoder/plugins/LameEncoderPlugin.cxx +++ b/src/encoder/plugins/LameEncoderPlugin.cxx @@ -30,15 +30,13 @@ #include #include -#include - class LameEncoder final : public Encoder { const AudioFormat audio_format; lame_global_flags *const gfp; - ReusableArray output_buffer; - unsigned char *output_begin = nullptr, *output_end = nullptr; + ReusableArray output_buffer; + std::span output{}; public: LameEncoder(const AudioFormat _audio_format, @@ -172,7 +170,7 @@ LameEncoder::Write(std::span _src) { const auto src = FromBytesStrict(_src); - assert(output_begin == output_end); + assert(output.empty()); const std::size_t num_samples = src.size(); const std::size_t num_frames = num_samples / audio_format.channels; @@ -186,27 +184,19 @@ LameEncoder::Write(std::span _src) int bytes_out = lame_encode_buffer_interleaved(gfp, const_cast(src.data()), num_frames, - dest, output_buffer_size); + (unsigned char *)dest, + output_buffer_size); if (bytes_out < 0) throw std::runtime_error("lame encoder failed"); - output_begin = dest; - output_end = dest + bytes_out; + output = {dest, std::size_t(bytes_out)}; } std::span -LameEncoder::Read(std::span buffer) noexcept +LameEncoder::Read(std::span) noexcept { - const auto begin = output_begin; - assert(begin <= output_end); - const std::size_t remainning = output_end - begin; - const std::size_t nbytes = std::min(remainning, buffer.size()); - - memcpy(buffer.data(), begin, nbytes); - - output_begin = begin + nbytes; - return buffer.first(nbytes); + return std::exchange(output, std::span{}); } const EncoderPlugin lame_encoder_plugin = { diff --git a/src/encoder/plugins/TwolameEncoderPlugin.cxx b/src/encoder/plugins/TwolameEncoderPlugin.cxx index 65c1de3d6..20b6950f4 100644 --- a/src/encoder/plugins/TwolameEncoderPlugin.cxx +++ b/src/encoder/plugins/TwolameEncoderPlugin.cxx @@ -31,16 +31,13 @@ #include #include -#include - class TwolameEncoder final : public Encoder { const AudioFormat audio_format; twolame_options *options; - unsigned char output_buffer[32768]; - std::size_t output_buffer_length = 0; - std::size_t output_buffer_position = 0; + std::byte output_buffer[32768]; + std::size_t fill = 0; /** * Call libtwolame's flush function when the output_buffer is @@ -192,46 +189,36 @@ TwolameEncoder::Write(std::span _src) { const auto src = FromBytesStrict(_src); - assert(output_buffer_position == output_buffer_length); + assert(fill == 0); const std::size_t num_frames = src.size() / audio_format.channels; int bytes_out = twolame_encode_buffer_interleaved(options, src.data(), num_frames, - output_buffer, + (unsigned char *)output_buffer, sizeof(output_buffer)); if (bytes_out < 0) throw std::runtime_error("twolame encoder failed"); - output_buffer_length = (std::size_t)bytes_out; - output_buffer_position = 0; + fill = (std::size_t)bytes_out; } std::span -TwolameEncoder::Read(std::span buffer) noexcept +TwolameEncoder::Read(std::span) noexcept { - assert(output_buffer_position <= output_buffer_length); + assert(fill <= sizeof(output_buffer)); - if (output_buffer_position == output_buffer_length && flush) { - int ret = twolame_encode_flush(options, output_buffer, + if (fill == 0 && flush) { + int ret = twolame_encode_flush(options, + (unsigned char *)output_buffer, sizeof(output_buffer)); - if (ret > 0) { - output_buffer_length = (size_t)ret; - output_buffer_position = 0; - } + if (ret > 0) + fill = (std::size_t)ret; flush = false; } - - const std::size_t remainning = output_buffer_length - output_buffer_position; - const std::size_t nbytes = std::min(remainning, buffer.size()); - - memcpy(buffer.data(), output_buffer + output_buffer_position, nbytes); - - output_buffer_position += nbytes; - - return buffer.first(nbytes); + return std::span{output_buffer}.first(std::exchange(fill, 0)); } const EncoderPlugin twolame_encoder_plugin = {