[flac-dev] C API: How to get a seektable for very long files?

Stefan Oltmanns stefan-oltmanns at gmx.net
Sun Oct 20 01:07:59 UTC 2024


Am 16.10.24 um 19:46 schrieb Martijn van Beurden:
> libFLAC reads a file from start to back, and returns data to the
> client as soon as it is done parsing. So, it first encounters a
> streaminfo metadata block, sends that to the application, then starts
> on the seektable etc. In fact, for a lot of applications, the seek
> table is simply ignored because libFLAC uses it internally.
>
> I don't know how libFLAC should indicate that streaminfo isn't
> complete yet, but I'd say getting applications to understand that is
> more work than them just supporting a new function that returns the
> total number of samples.

I did some tests and "hacked" that feature into libFLAC: During encoding
it will always set the last seekpoint to the last written frame (after
sorting that is the last seekpoint before the placeholder start). It
will then later write that special placeholder and for decoding during
parsing the seektable it will adjust total samples.

Of course the problem is that the streaminfo callback is called before
the seektable is parsed. A modification to call the streaminfo callback
later is no problem and the flac application works fine with it, it will
then perfectly display the percentage during decode.
But the streaminfo block is mandatory first, so there might be
applications out there that expect the streaminfo callback called first.
Of course you could delay all callbacks and later call them in the right
order, but that would require reading a lot of data before the first
callback is called, not sure if that could break applications.

Overall: I don't think this a solution that could be implemented nicely
in libflac.

Additionally when I tried seeking in audio players I had to notice: They
don't seem to use libflac at all, but libavcodec (ffmpeg). I quickly
checked the ffmpeg source, I don't think they parse the seektable at
all. The same problem here, it would have to read a lot of data before
the length can be figured out.

I think a much better way would be: define a new metadata block like
"STREAMINFO_EXT", that is of course optional, but if it exists it has to
follow directly the STREAMINFO block. libflac could delay calling the
STREAMINFO callback exactly one block: If STREAMINFO is not the last
block, it will not call the callback, it will read the next block, if it
is "STREAMINFO_EXT" it will update the stream information and then call
the streaminfo callback (and maybe call a streaminfo_ext callback), if
it is something else it will directly call the streaminfo callback.

I'm not sure what else there could be in "STREAMINFO_EXT" except for
total samples and sample rate, but maybe there is some other use for (at
least partially) backward-compatible flac extensions.

Adding that to ffmpeg would also be rather simple.

Best regards
Stefan



More information about the flac-dev mailing list