mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 06:57:46 +00:00
LibAudio: Avoid frequent read() calls in FLAC residual decode
Decoding the residual in FLAC subframes is by far the most I/O-heavy operation in FLAC decoding, as the residual data makes up the majority of subframe data in LPC subframes. As the residual consists of many Rice-encoded numbers with different bit sizes for differently large numbers, the residual decoder frequently reads only one or two bytes at a time. As we use a normal FileInputStream, that directly translates to many calls to the read() syscall. We can see that the I/O overhead while FLAC decoding is quite large, and much time is spent in the read() syscall's kernel code. This is optimized by using a Buffered<FileInputStream> instead, leading to 4K blocks being read at once and a large reduction in I/O overhead. Benchmarking with the new abench utility gives a 15-20% speedup on identical files, usually pushing FLAC decoding to 10-15x realtime speed on common sample rates.
This commit is contained in:
parent
cbb2b4fe71
commit
14d330faba
2 changed files with 16 additions and 7 deletions
|
@ -28,9 +28,14 @@ FlacLoaderPlugin::FlacLoaderPlugin(StringView path)
|
|||
return;
|
||||
}
|
||||
|
||||
m_stream = make<FlacInputStream>(Core::InputFileStream(*m_file));
|
||||
auto maybe_stream = Core::InputFileStream::open_buffered(path);
|
||||
if (maybe_stream.is_error()) {
|
||||
m_error_string = "Can't open file stream";
|
||||
return;
|
||||
}
|
||||
m_stream = make<FlacInputStream>(maybe_stream.release_value());
|
||||
if (!m_stream) {
|
||||
m_error_string = String::formatted("Can't open memory stream");
|
||||
m_error_string = "Can't open file stream";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -69,7 +74,7 @@ bool FlacLoaderPlugin::parse_header()
|
|||
|
||||
InputBitStream bit_input = [&]() -> InputBitStream {
|
||||
if (m_file) {
|
||||
return InputBitStream(m_stream->get<Core::InputFileStream>());
|
||||
return InputBitStream(m_stream->get<Buffered<Core::InputFileStream>>());
|
||||
}
|
||||
return InputBitStream(m_stream->get<InputMemoryStream>());
|
||||
}();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue