Stefan Oltmanns
2024-Oct-20 01:07 UTC
[flac-dev] C API: How to get a seektable for very long files?
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
Martijn van Beurden
2024-Oct-20 12:44 UTC
[flac-dev] C API: How to get a seektable for very long files?
Op zo 20 okt 2024 om 03:08 schreef Stefan Oltmanns <stefan-oltmanns at gmx.net>:> > 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. >As with any such change, it will take a lot of time to bring all applications up to date. As you say, a lot of applications use ffmpeg/libavcodec instead. A much easier solution, which works with ffmpeg right out of the box, even with older distributions (such as Ubuntu 22.04 you mention) is to use the wavpack codec instead of flac. It supports samplerates up to 1 GHz, has an arguably better way of seeking, supports a 40 bit number for samples and has a non-perceptual lossy option which might actually work very well for your usecase. hz A lot of editing applications supporting FLAC also support Wavpack, often through ffmpeg. The only downsides are that the 40 bit sample number seems a hard limit and decoding is a bit slower. The 40-bit number still correlates to 7.5 hours at 40MHz though.