encoder/lame: Read() returns the internal buffer
Eliminate memcpy() calls.
This commit is contained in:
parent
0d09f307b2
commit
c266fb7758
@ -30,15 +30,13 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
class LameEncoder final : public Encoder {
|
class LameEncoder final : public Encoder {
|
||||||
const AudioFormat audio_format;
|
const AudioFormat audio_format;
|
||||||
|
|
||||||
lame_global_flags *const gfp;
|
lame_global_flags *const gfp;
|
||||||
|
|
||||||
ReusableArray<unsigned char, 32768> output_buffer;
|
ReusableArray<std::byte, 32768> output_buffer;
|
||||||
unsigned char *output_begin = nullptr, *output_end = nullptr;
|
std::span<const std::byte> output{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LameEncoder(const AudioFormat _audio_format,
|
LameEncoder(const AudioFormat _audio_format,
|
||||||
@ -172,7 +170,7 @@ LameEncoder::Write(std::span<const std::byte> _src)
|
|||||||
{
|
{
|
||||||
const auto src = FromBytesStrict<const int16_t>(_src);
|
const auto src = FromBytesStrict<const int16_t>(_src);
|
||||||
|
|
||||||
assert(output_begin == output_end);
|
assert(output.empty());
|
||||||
|
|
||||||
const std::size_t num_samples = src.size();
|
const std::size_t num_samples = src.size();
|
||||||
const std::size_t num_frames = num_samples / audio_format.channels;
|
const std::size_t num_frames = num_samples / audio_format.channels;
|
||||||
@ -186,27 +184,19 @@ LameEncoder::Write(std::span<const std::byte> _src)
|
|||||||
int bytes_out = lame_encode_buffer_interleaved(gfp,
|
int bytes_out = lame_encode_buffer_interleaved(gfp,
|
||||||
const_cast<short *>(src.data()),
|
const_cast<short *>(src.data()),
|
||||||
num_frames,
|
num_frames,
|
||||||
dest, output_buffer_size);
|
(unsigned char *)dest,
|
||||||
|
output_buffer_size);
|
||||||
|
|
||||||
if (bytes_out < 0)
|
if (bytes_out < 0)
|
||||||
throw std::runtime_error("lame encoder failed");
|
throw std::runtime_error("lame encoder failed");
|
||||||
|
|
||||||
output_begin = dest;
|
output = {dest, std::size_t(bytes_out)};
|
||||||
output_end = dest + bytes_out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::span<const std::byte>
|
std::span<const std::byte>
|
||||||
LameEncoder::Read(std::span<std::byte> buffer) noexcept
|
LameEncoder::Read(std::span<std::byte>) noexcept
|
||||||
{
|
{
|
||||||
const auto begin = output_begin;
|
return std::exchange(output, std::span<const std::byte>{});
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const EncoderPlugin lame_encoder_plugin = {
|
const EncoderPlugin lame_encoder_plugin = {
|
||||||
|
@ -31,16 +31,13 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
class TwolameEncoder final : public Encoder {
|
class TwolameEncoder final : public Encoder {
|
||||||
const AudioFormat audio_format;
|
const AudioFormat audio_format;
|
||||||
|
|
||||||
twolame_options *options;
|
twolame_options *options;
|
||||||
|
|
||||||
unsigned char output_buffer[32768];
|
std::byte output_buffer[32768];
|
||||||
std::size_t output_buffer_length = 0;
|
std::size_t fill = 0;
|
||||||
std::size_t output_buffer_position = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call libtwolame's flush function when the output_buffer is
|
* Call libtwolame's flush function when the output_buffer is
|
||||||
@ -192,46 +189,36 @@ TwolameEncoder::Write(std::span<const std::byte> _src)
|
|||||||
{
|
{
|
||||||
const auto src = FromBytesStrict<const int16_t>(_src);
|
const auto src = FromBytesStrict<const int16_t>(_src);
|
||||||
|
|
||||||
assert(output_buffer_position == output_buffer_length);
|
assert(fill == 0);
|
||||||
|
|
||||||
const std::size_t num_frames = src.size() / audio_format.channels;
|
const std::size_t num_frames = src.size() / audio_format.channels;
|
||||||
|
|
||||||
int bytes_out = twolame_encode_buffer_interleaved(options,
|
int bytes_out = twolame_encode_buffer_interleaved(options,
|
||||||
src.data(), num_frames,
|
src.data(), num_frames,
|
||||||
output_buffer,
|
(unsigned char *)output_buffer,
|
||||||
sizeof(output_buffer));
|
sizeof(output_buffer));
|
||||||
if (bytes_out < 0)
|
if (bytes_out < 0)
|
||||||
throw std::runtime_error("twolame encoder failed");
|
throw std::runtime_error("twolame encoder failed");
|
||||||
|
|
||||||
output_buffer_length = (std::size_t)bytes_out;
|
fill = (std::size_t)bytes_out;
|
||||||
output_buffer_position = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::span<const std::byte>
|
std::span<const std::byte>
|
||||||
TwolameEncoder::Read(std::span<std::byte> buffer) noexcept
|
TwolameEncoder::Read(std::span<std::byte>) noexcept
|
||||||
{
|
{
|
||||||
assert(output_buffer_position <= output_buffer_length);
|
assert(fill <= sizeof(output_buffer));
|
||||||
|
|
||||||
if (output_buffer_position == output_buffer_length && flush) {
|
if (fill == 0 && flush) {
|
||||||
int ret = twolame_encode_flush(options, output_buffer,
|
int ret = twolame_encode_flush(options,
|
||||||
|
(unsigned char *)output_buffer,
|
||||||
sizeof(output_buffer));
|
sizeof(output_buffer));
|
||||||
if (ret > 0) {
|
if (ret > 0)
|
||||||
output_buffer_length = (size_t)ret;
|
fill = (std::size_t)ret;
|
||||||
output_buffer_position = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
flush = false;
|
flush = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return std::span{output_buffer}.first(std::exchange(fill, 0));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const EncoderPlugin twolame_encoder_plugin = {
|
const EncoderPlugin twolame_encoder_plugin = {
|
||||||
|
Loading…
Reference in New Issue
Block a user